<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>

<link href='https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color:#ffffff; --text-color:#333333; --select-text-bg-color:#B5D6FC; --select-text-font-color:auto; --monospace:"Lucida Console",Consolas,"Courier",monospace; --title-bar-height:20px; }
.mac-os-11 { --title-bar-height:28px; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; tab-size: 4; }
iframe { margin: auto; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; overflow-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; }
#write.first-line-indent p { text-indent: 2em; }
#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }
#write.first-line-indent li { margin-left: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }
.typora-export .task-list-item input { pointer-events: none; }
@media screen and (max-width: 500px) {
  body.typora-export { padding-left: 0px; padding-right: 0px; }
  #write { padding-left: 20px; padding-right: 20px; }
}
#write li > figure:last-child { margin-bottom: 0.5rem; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; image-orientation: from-image; }
button, input, select, textarea { color: inherit; font: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
p { line-height: inherit; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px; }
thead, tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 32px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror-linenumber { user-select: none; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
svg { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li blockquote { margin: 1rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
  body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; }
  #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; padding-bottom: 0px !important; }
  .typora-export * { -webkit-print-color-adjust: exact; }
  .typora-export #write { break-after: avoid; }
  .typora-export #write::after { height: 0px; }
  .is-mac table { break-inside: avoid; }
  .typora-export-show-outline .typora-export-sidebar { display: none; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
#write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; }
p > .md-image:only-child { display: inline-block; width: 100%; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
.MathJax_ref { fill: currentcolor; }
[contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
  .md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
  .md-toc-h4 .md-toc-inner { margin-left: 5em; }
  .md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
  .md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.reversefootnote { font-family: ui-monospace, sans-serif; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.6; font-family: var(--monospace); }
code { text-align: left; vertical-align: initial; }
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }
mark { background: rgb(255, 255, 0); color: rgb(0, 0, 0); }
.md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; }
.md-expand mark .md-meta { opacity: 0.3 !important; }
mark .md-meta { color: rgb(0, 0, 0); }
@media print {
  .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; }
}
.md-diagram-panel .messageText { stroke: none !important; }
.md-diagram-panel .start-state { fill: var(--node-fill); }
.md-diagram-panel .edgeLabel rect { opacity: 1 !important; }
.md-fences.md-fences-math { font-size: 1em; }
.md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; }
.md-fences-advanced:not(.md-focus) { background: inherit; }
.typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; }
.typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; }
.typora-export-show-outline #write { --webkit-flex:2; flex: 2 1 0%; }
.typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; }
@media screen and (max-width: 1024px) {
  .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; }
}
@media screen and (max-width: 800px) {
  .typora-export-sidebar { display: none; }
}
.outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; }
.outline-content ul { margin-top: 0px; margin-bottom: 0px; }
.outline-content strong { font-weight: 400; }
.outline-expander { width: 1rem; height: 1.42857rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; }
.outline-expander::before { content: ""; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; }
.outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; }
.outline-expander:hover::before { content: ""; }
.outline-h1 > .outline-item { padding-left: 0px; }
.outline-h2 > .outline-item { padding-left: 1em; }
.outline-h3 > .outline-item { padding-left: 2em; }
.outline-h4 > .outline-item { padding-left: 3em; }
.outline-h5 > .outline-item { padding-left: 4em; }
.outline-h6 > .outline-item { padding-left: 5em; }
.outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; }
.outline-label:hover { text-decoration: underline; }
.outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); }
.outline-item:hover { margin-left: -28px; margin-right: -28px; border-left: 28px solid transparent; border-right: 28px solid transparent; }
.outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; }
.outline-item-open > .outline-item > .outline-expander::before { content: ""; }
.outline-children { display: none; }
.info-panel-tab-wrapper { display: none; }
.outline-item-open > .outline-children { display: block; }
.typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; }
.typora-export .outline-item:hover { margin-right: -8px; border-right: 8px solid transparent; }
.typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; }
.typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: "−"; }
.typora-export-collapse-outline .outline-children { display: none; }
.typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; }
.typora-export-no-collapse-outline .outline-expander::before { content: "" !important; }
.typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; }
.md-inline-math-container mjx-container { zoom: 0.95; }


.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background: inherit; }
.CodeMirror-scroll { overflow: auto hidden; z-index: 3; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; outline: 0px; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: auto hidden; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 10px; z-index: 3; overflow-y: hidden; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; overflow-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { overflow-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
span.cm-underlined { text-decoration: underline; }
span.cm-strikethrough { text-decoration: line-through; }
.cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); }
.cm-tw-deleted { text-decoration: line-through; }
.cm-tw-header5 { font-weight: 700; }
.cm-tw-listitem:first-child { padding-left: 10px; }
.cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; }
.cm-tw-underline { text-decoration: underline; }
@media print {
  .CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}


:root {
    --side-bar-bg-color: #fafafa;
    --control-text-color: #777;
}

@include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);

/* open-sans-regular - latin-ext_latin */
  /* open-sans-italic - latin-ext_latin */
    /* open-sans-700 - latin-ext_latin */
    /* open-sans-700italic - latin-ext_latin */
  html {
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
}

body {
    font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, 'Segoe UI Emoji', sans-serif;
    color: rgb(51, 51, 51);
    line-height: 1.6;
}

#write {
    max-width: 860px;
  	margin: 0 auto;
  	padding: 30px;
    padding-bottom: 100px;
}

@media only screen and (min-width: 1400px) {
	#write {
		max-width: 1024px;
	}
}

@media only screen and (min-width: 1800px) {
	#write {
		max-width: 1200px;
	}
}

#write > ul:first-child,
#write > ol:first-child{
    margin-top: 30px;
}

a {
    color: #4183C4;
}
h1,
h2,
h3,
h4,
h5,
h6 {
    position: relative;
    margin-top: 1rem;
    margin-bottom: 1rem;
    font-weight: bold;
    line-height: 1.4;
    cursor: text;
}
h1:hover a.anchor,
h2:hover a.anchor,
h3:hover a.anchor,
h4:hover a.anchor,
h5:hover a.anchor,
h6:hover a.anchor {
    text-decoration: none;
}
h1 tt,
h1 code {
    font-size: inherit;
}
h2 tt,
h2 code {
    font-size: inherit;
}
h3 tt,
h3 code {
    font-size: inherit;
}
h4 tt,
h4 code {
    font-size: inherit;
}
h5 tt,
h5 code {
    font-size: inherit;
}
h6 tt,
h6 code {
    font-size: inherit;
}
h1 {
    font-size: 2.25em;
    line-height: 1.2;
    border-bottom: 1px solid #eee;
}
h2 {
    font-size: 1.75em;
    line-height: 1.225;
    border-bottom: 1px solid #eee;
}

/*@media print {
    .typora-export h1,
    .typora-export h2 {
        border-bottom: none;
        padding-bottom: initial;
    }

    .typora-export h1::after,
    .typora-export h2::after {
        content: "";
        display: block;
        height: 100px;
        margin-top: -96px;
        border-top: 1px solid #eee;
    }
}*/

h3 {
    font-size: 1.5em;
    line-height: 1.43;
}
h4 {
    font-size: 1.25em;
}
h5 {
    font-size: 1em;
}
h6 {
   font-size: 1em;
    color: #777;
}
p,
blockquote,
ul,
ol,
dl,
table{
    margin: 0.8em 0;
}
li>ol,
li>ul {
    margin: 0 0;
}
hr {
    height: 2px;
    padding: 0;
    margin: 16px 0;
    background-color: #e7e7e7;
    border: 0 none;
    overflow: hidden;
    box-sizing: content-box;
}

li p.first {
    display: inline-block;
}
ul,
ol {
    padding-left: 30px;
}
ul:first-child,
ol:first-child {
    margin-top: 0;
}
ul:last-child,
ol:last-child {
    margin-bottom: 0;
}
blockquote {
    border-left: 4px solid #dfe2e5;
    padding: 0 15px;
    color: #777777;
}
blockquote blockquote {
    padding-right: 0;
}
table {
    padding: 0;
    word-break: initial;
}
table tr {
    border: 1px solid #dfe2e5;
    margin: 0;
    padding: 0;
}
table tr:nth-child(2n),
thead {
    background-color: #f8f8f8;
}
table th {
    font-weight: bold;
    border: 1px solid #dfe2e5;
    border-bottom: 0;
    margin: 0;
    padding: 6px 13px;
}
table td {
    border: 1px solid #dfe2e5;
    margin: 0;
    padding: 6px 13px;
}
table th:first-child,
table td:first-child {
    margin-top: 0;
}
table th:last-child,
table td:last-child {
    margin-bottom: 0;
}

.CodeMirror-lines {
    padding-left: 4px;
}

.code-tooltip {
    box-shadow: 0 1px 1px 0 rgba(0,28,36,.3);
    border-top: 1px solid #eef2f2;
}

.md-fences,
code,
tt {
    border: 1px solid #e7eaed;
    background-color: #f8f8f8;
    border-radius: 3px;
    padding: 0;
    padding: 2px 4px 0px 4px;
    font-size: 0.9em;
}

code {
    background-color: #f3f4f4;
    padding: 0 2px 0 2px;
}

.md-fences {
    margin-bottom: 15px;
    margin-top: 15px;
    padding-top: 8px;
    padding-bottom: 6px;
}


.md-task-list-item > input {
  margin-left: -1.3em;
}

@media print {
    html {
        font-size: 13px;
    }
    pre {
        page-break-inside: avoid;
        word-wrap: break-word;
    }
}

.md-fences {
	background-color: #f8f8f8;
}
#write pre.md-meta-block {
	padding: 1rem;
    font-size: 85%;
    line-height: 1.45;
    background-color: #f7f7f7;
    border: 0;
    border-radius: 3px;
    color: #777777;
    margin-top: 0 !important;
}

.mathjax-block>.code-tooltip {
	bottom: .375rem;
}

.md-mathjax-midline {
    background: #fafafa;
}

#write>h3.md-focus:before{
	left: -1.5625rem;
	top: .375rem;
}
#write>h4.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
#write>h5.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
#write>h6.md-focus:before{
	left: -1.5625rem;
	top: .285714286rem;
}
.md-image>.md-meta {
    /*border: 1px solid #ddd;*/
    border-radius: 3px;
    padding: 2px 0px 0px 4px;
    font-size: 0.9em;
    color: inherit;
}

.md-tag {
    color: #a7a7a7;
    opacity: 1;
}

.md-toc { 
    margin-top:20px;
    padding-bottom:20px;
}

.sidebar-tabs {
    border-bottom: none;
}

#typora-quick-open {
    border: 1px solid #ddd;
    background-color: #f8f8f8;
}

#typora-quick-open-item {
    background-color: #FAFAFA;
    border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee;
    border-style: solid;
    border-width: 1px;
}

/** focus mode */
.on-focus-mode blockquote {
    border-left-color: rgba(85, 85, 85, 0.12);
}

header, .context-menu, .megamenu-content, footer{
    font-family: "Segoe UI", "Arial", sans-serif;
}

.file-node-content:hover .file-node-icon,
.file-node-content:hover .file-node-open-state{
    visibility: visible;
}

.mac-seamless-mode #typora-sidebar {
    background-color: #fafafa;
    background-color: var(--side-bar-bg-color);
}

.md-lang {
    color: #b4654d;
}

/*.html-for-mac {
    --item-hover-bg-color: #E6F0FE;
}*/

#md-notification .btn {
    border: 0;
}

.dropdown-menu .divider {
    border-color: #e5e5e5;
    opacity: 0.4;
}

.ty-preferences .window-content {
    background-color: #fafafa;
}

.ty-preferences .nav-group-item.active {
    color: white;
    background: #999;
}

.menu-item-container a.menu-style-btn {
    background-color: #f5f8fa;
    background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); 
}



</style><title>物联网平台开发及使用手册</title>
</head>
<body class='typora-export os-windows typora-export-show-outline typora-export-collapse-outline'><div class='typora-export-content'>
<div class="typora-export-sidebar"><div class="outline-content"><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#0-前言说明">0 前言说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#01-编译说明">0.1 编译说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#02-功能特点">0.2 功能特点</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#021-软件模块">0.2.1 软件模块</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#022-基础功能">0.2.2 基础功能</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#023-特色功能">0.2.3 特色功能</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#03-相关站点">0.3 相关站点</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#04-特别说明">0.4 特别说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#05-简易操作">0.5 简易操作</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#06-版本说明">0.6 版本说明</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1-用户登录退出">1 用户登录退出</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11-用户登录">1.1 用户登录</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#12-用户退出">1.2 用户退出</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#2-系统设置">2 系统设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#21-基本设置">2.1 基本设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#211-常规设置">2.1.1 常规设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#212-本地数据库设置">2.1.2 本地数据库设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#213-云端数据库同步">2.1.3 云端数据库同步</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#214-日志设置">2.1.4 日志设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#215-网络转发设置">2.1.5 网络转发设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#216-告警短信转发">2.1.6 告警短信转发</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#217-告警邮件转发">2.1.7 告警邮件转发</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#218-系统时间设置">2.1.8 系统时间设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#219-功能激活">2.1.9 功能激活</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#2110-颜色设置">2.1.10 颜色设置</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#22-端口管理">2.2 端口管理</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#221-端口添加">2.2.1 端口添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#222-端口删除">2.2.2 端口删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#223-端口清空">2.2.3 端口清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#224-端口信息导入">2.2.4 端口信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#225-端口信息导出">2.2.5 端口信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#226-端口信息打印">2.2.6 端口信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#227-导出到excel">2.2.7 导出到Excel</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#23-控制器管理">2.3 控制器管理</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#231-控制器添加">2.3.1 控制器添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#232-控制器删除">2.3.2 控制器删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#233-控制器清空">2.3.3 控制器清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#234-控制器信息导入">2.3.4 控制器信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#235-控制器信息导出">2.3.5 控制器信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#236-控制器信息打印">2.3.6 控制器信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#237-导出到excel">2.3.7 导出到Excel</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#24-探测器管理">2.4 探测器管理</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#241-探测器添加">2.4.1 探测器添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#242-探测器删除">2.4.2 探测器删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#243-探测器清空">2.4.3 探测器清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#244-探测器信息导入">2.4.4 探测器信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#245-探测器信息导出">2.4.5 探测器信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#246-探测器信息打印">2.4.6 探测器信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#247-导出到excel">2.4.7 导出到Excel</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#25-报警联动">2.5 报警联动</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#251-联动添加">2.5.1 联动添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#252-联动删除">2.5.2 联动删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#253-联动清空">2.5.3 联动清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#254-联动信息导入">2.5.4 联动信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#255-联动信息导出">2.5.5 联动信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#256-联动信息打印">2.5.6 联动信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#257-导出到excel">2.5.7 导出到Excel</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#26-类型设置">2.6 类型设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#261-类型添加">2.6.1 类型添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#262-类型删除">2.6.2 类型删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#263-类型清空">2.6.3 类型清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#264-类型信息导入">2.6.4 类型信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#265-类型信息导出">2.6.5 类型信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#266-类型信息打印">2.6.6 类型信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#267-导出到excel">2.6.7 导出到Excel</a></div><ul class="outline-children"></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#3-其他设置">3 其他设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#31-用户管理">3.1 用户管理</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#311-用户添加">3.1.1 用户添加</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#312-用户删除">3.1.2 用户删除</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#313-用户清空">3.1.3 用户清空</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#314-用户信息导入">3.1.4 用户信息导入</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#315-用户信息导出">3.1.5 用户信息导出</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#316-用户信息打印">3.1.6 用户信息打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#317-导出到excel">3.1.7 导出到Excel</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#318-权限验证">3.1.8 权限验证</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#32-地图管理">3.2 地图管理</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#33-位置调整">3.3 位置调整</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#34-组态设计">3.4 组态设计</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#35-设备调试">3.5 设备调试</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#4-设备监控">4 设备监控</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#41-数据监控">4.1 数据监控</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#42-设备面板">4.2 设备面板</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#421-普通样式">4.2.1 普通样式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#422-仪表样式">4.2.2 仪表样式</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#423-仪表样式2">4.2.3 仪表样式2</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#43-地图监控">4.3 地图监控</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#44-曲线监控">4.4 曲线监控</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#441-实时曲线">4.4.1 实时曲线</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#442-历史曲线">4.4.2 历史曲线</a></div><ul class="outline-children"></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#5-数据查询">5 数据查询</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#51-报警记录">5.1 报警记录</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#511-记录查询">5.1.1 记录查询</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#512-记录打印">5.1.2 记录打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#513-记录导出">5.1.3 记录导出</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#52-运行记录">5.2 运行记录</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#521-记录查询">5.2.1 记录查询</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#522-记录打印">5.2.2 记录打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#523-记录导出">5.2.3 记录导出</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#53-操作记录">5.3 操作记录</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#531-记录查询">5.3.1 记录查询</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#532-记录打印">5.3.2 记录打印</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#533-记录导出">5.3.3 记录导出</a></div><ul class="outline-children"></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#6-通信协议">6 通信协议</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#61-通信流程">6.1 通信流程</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#611-fc1003-1">6.1.1 FC1003-1</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#612-fc1003-8">6.1.2 FC1003-8</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#613-fc1003-16">6.1.3 FC1003-16</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#614-fc1103显示板">6.1.4 FC1103显示板</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#615-sams-4128">6.1.5 SAMS-4128</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#616-ft21047p">6.1.6 FT21047P</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#62-协议解释">6.2 协议解释</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#621-主机发送">6.2.1 主机发送</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#622-从机应答">6.2.2 从机应答</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#623-读取长度">6.2.3 读取长度</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#624-数据举例">6.2.4 数据举例</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#625-继电器联动">6.2.5 继电器联动</a></div><ul class="outline-children"></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#7-各系统运行图">7 各系统运行图</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#70-样式风格">7.0 样式风格</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#71-windows-mingw">7.1 windows-mingw</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#72-windows-msvc">7.2 windows-msvc</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#73-linux-ubuntu">7.3 linux-ubuntu</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#74-linux-uos">7.4 linux-uos</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#75-linux-kylin">7.5 linux-kylin</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#76-linux-neokylin">7.6 linux-neokylin</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#77-linux-centos">7.7 linux-centos</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#78-linux-fedora">7.8 linux-fedora</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#79-unix-mac">7.9 unix-mac</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8-程序框架说明">8 程序框架说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#81-整体代码结构">8.1 整体代码结构</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#82-主模块说明">8.2 主模块说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#83-子模块说明">8.3 子模块说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#831-第三方类库">8.3.1 第三方类库</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#832-通信及辅助类">8.3.2 通信及辅助类</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8321-模块-api">8.3.2.1 模块-api</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8322-模块-app">8.3.2.2 模块-app</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8323-模块-device">8.3.2.3 模块-device</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8324-模块-usercontrol">8.3.2.4 模块-usercontrol</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h4"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#833-核心通用类库">8.3.3 核心通用类库</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8331-模块-corecommon">8.3.3.1 模块-core_common</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8332-模块-corecontrol">8.3.3.2 模块-core_control</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8333-模块-corecustomplot">8.3.3.3 模块-core_customplot</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8334-模块-coredataout">8.3.3.4 模块-core_dataout</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8335-模块-coredb">8.3.3.5 模块-core_db</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8336-模块-coreform">8.3.3.6 模块-core_form</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8337-模块-corequi">8.3.3.7 模块-core_qui</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8338-模块-coresend">8.3.3.8 模块-core_send</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h4"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#834-界面ui">8.3.4 界面UI</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8341-模块-frmconfig">8.3.4.1 模块-frmconfig</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8342-模块-frmconfig2">8.3.4.2 模块-frmconfig2</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8343-模块-frmdata">8.3.4.3 模块-frmdata</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8344-模块-frmmain">8.3.4.4 模块-frmmain</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8345-模块-frmother">8.3.4.5 模块-frmother</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h5 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8346-模块-frmview">8.3.4.6 模块-frmview</a></div><ul class="outline-children"></ul></li></ul></li></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#9-数据库设计">9 数据库设计</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#91-端口信息-portinfo">9.1 端口信息-PortInfo</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#92-控制器信息-deviceinfo">9.2 控制器信息-DeviceInfo</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#93-探测器信息-nodeinfo">9.3 探测器信息-NodeInfo</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#94-报警联动-alarmlink">9.4 报警联动-AlarmLink</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#95-类型信息-typeinfo">9.5 类型信息-TypeInfo</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#96-节点数据-nodedata">9.6 节点数据-NodeData</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#97-用户信息-userinfo">9.7 用户信息-UserInfo</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#98-操作记录-userlog">9.8 操作记录-UserLog</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#99-运行记录-nodelog">9.9 运行记录-NodeLog</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#910-报警记录-alarmlog">9.10 报警记录-AlarmLog</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#10-其他说明">10 其他说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#101-设备模拟工具">10.1 设备模拟工具</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#102-modbus仿真">10.2 modbus仿真</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#103-邮件转发设置">10.3 邮件转发设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#104-短信转发设置">10.4 短信转发设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#105-代码行数统计">10.5 代码行数统计</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#106-多种数据库支持">10.6 多种数据库支持</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1061-sqlite">10.6.1 sqlite</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1062-mysql">10.6.2 mysql</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1063-sqlserver">10.6.3 sqlserver</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1064-postgresql">10.6.4 postgresql</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1065-oracle">10.6.5 oracle</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1066-kingbase">10.6.6 kingbase</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#107-采集数据转发">10.7 采集数据转发</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#108-云端数据库同步">10.8 云端数据库同步</a></div><ul class="outline-children"></ul></li></ul></li></div></div><div id='write'  class=''><h2 id='0-前言说明'><span>0 前言说明</span></h2><h3 id='01-编译说明'><span>0.1 编译说明</span></h3><ol start='' ><li><span>编译完成后记得将源码下的file目录下（切记是file目录下而不是file目录）的所有文件复制到可执行文件同一目录。可执行文件目录bin在当前源码下，和一堆core开头的目录同级别，编译后会自动生成bin目录。</span></li><li><span>打开pro文件，修改DEFINES中的 iottool1 为 iottool，则编译出来的是设备模拟工具，用于没有外接硬件设备时候模拟设备数据测试用。</span></li><li><span>编译完成后，先双击打开iottool.exe，这个是设备模拟工具，再打开iotsystem.exe，这个是主程序，主程序建议添加两个通信端口，一个串口端口和一个网络端口，设备模拟工具会自动打开串口和网络进行数据的模拟。</span></li><li><span>db目录下的 iotsystem.mbs 为modbus模拟数据模板，可以用modbus slave软件打开。</span></li><li><span>db目录为数据库文件夹，iotsystem.db为sqlite数据库文件，sql结尾的为建库脚本，可以自行改成mysql数据库。</span></li><li><span>在端口设置中如果不填写串口号则取网络地址，填了串口号则以串口号优先。</span></li><li><span>如果导出的数据到excel以后，打开文件有提示，请先执行db目录下的excel禁止提示.reg文件。</span></li><li><span>系统中的组态模块用到了designer模块，有些linux系统安装的Qt开发环境可能会不自带这个模块，编译的时候报错提示 Project ERROR: Unknown module(s) in QT: designer，需要手动打命令安装下，sudo apt-get install libqt5designer5 或者 sudo apt-get install qttools5-dev 。</span></li></ol><h3 id='02-功能特点'><span>0.2 功能特点</span></h3><h4 id='021-软件模块'><span>0.2.1 软件模块</span></h4><ol start='' ><li><span>设备监控模块，包括数据监控（表格形式展示）、设备面板（面板形式展示）、地图监控（地图形式展示）、曲线监控（曲线形式展示）。</span></li><li><span>数据查询模块，包括报警记录、运行记录、操作记录。</span></li><li><span>系统设置模块，包括基本设置、端口管理、控制器管理、探测器管理、报警联动、类型设置等。</span></li><li><span>其他设置模块，包括用户管理、地图管理、位置调整、组态设计、设备调试等。</span></li></ol><h4 id='022-基础功能'><span>0.2.2 基础功能</span></h4><ol start='' ><li><span>设备数据采集，支持串口、网络，串口可设置串口号、波特率，网络可设置IP地址、通讯端口。</span></li><li><span>每个端口支持采集周期时间，默认1秒钟一个设备。</span></li><li><span>支持设置通讯超时次数，默认3次。</span></li><li><span>支持最大重连时间，用于重新读取离线的设备。</span></li><li><span>控制器信息，能够添加控制器名称，选择控制器地址、控制器型号，设置该控制器下面的探测器数量。</span></li><li><span>探测器信息，能够添加位号、探测器型号、气体种类、气体符号、高报值、低报值、缓冲值、清零值、是否启用、报警声音、背景地图、存储周期、数值换算小数点位数、报警延时时间、报警的类型（HH,LL,HL）等。</span></li><li><span>类型管理可配置控制器型号、探测器型号、气体种类、气体符号等。</span></li><li><span>地图支持导入和删除，所有的探测器在地图上的位置可自由拖动保存。</span></li><li><span>端口信息、控制器信息、探测器信息、类型信息、用户信息等，都支持导入、导出、导出到excel、打印。</span></li><li><span>运行记录、报警记录、操作记录，都支持多条件组合查询，比如时间段、控制器、探测器等，所有记录支持导出到excel/pdf和打印。</span></li><li><span>运行记录、报警记录、操作记录都可删除指定时间范围内的数据。</span></li><li><span>系统设置可选择对应表最大保存记录数，自动清理早期数据，留出足够的空间存储重要的数据。</span></li><li><span>报警短信转发，支持多个接收手机号码，可设定发送间隔，比如即时发送或者6个小时发送一次所有的报警信息，短信内容过长，自动拆分多条短信。</span></li><li><span>报警邮件转发，支持多个接收邮箱，可设定发送间隔，比如即时发送或者6个小时发送一次所有的报警信息，支持附件发送。</span></li><li><span>设置软件的中文标题、英文标题、logo路径、版权所有等。</span></li><li><span>开关设置开机运行、报警声音、自动登录、记住密码等。</span></li><li><span>报警声音可设置播放次数，界面风格样式提供18套皮肤文件选择。</span></li><li><span>用户管理，包括用户权限配置，不同用户可以有不同模块的权限。</span></li><li><span>用户登录和用户退出，可以记住密码和自动登录，超过三次报错提示并关闭程序。</span></li><li><span>四种监控模式，设备面板监控、地图监控、表格数据监控、曲线数据监控，可自由切换，四种模式下都实时展示采集到的数据，报警闪烁等。</span></li><li><span>报警继电器联动，一个位号可以跨串口联动多个模块和继电器号，支持多对多。</span></li></ol><h4 id='023-特色功能'><span>0.2.3 特色功能</span></h4><ol start='' ><li><span>通信协议支持modbus_com、modbus_tcp_rtu，后期拓展mqtt等协议。</span></li><li><span>数据源除了真实的硬件设备采集，还可选数据库采集，这样用户可以安排其他程序员比如java程序员将前端采集好的数据放到数据库，本系统直接从数据库采集即可。数据库采集模式可以作为通用的系统使用，更适合多人多系统协作。</span></li><li><span>智能跳过超时的设备，加快对在线设备的采集速度，当设备数量很多的时候尤其有用。</span></li><li><span>对智能跳过的超时的设备，在设定的重连时间自动采集一次，以便探测设备是否又重新上线。</span></li><li><span>每个探测器可控是否启用，不启用则不会采集，也不会在界面显示，相当于运行阶段临时关闭。</span></li><li><span>探测器可设置缓冲值和报警延时时间，在该值附近波动产生的报警，不计入报警，只有持续处于报警值且超过报警延时时间才算真正报警，这样可以规避很多波动导致的误报。</span></li><li><span>探测器可设置存储周期，按照设定的时间来存储一条运行记录，可以按照重要程度对重要性高的设定存储周期短一些，不重要的设定大一些，这样可以节省不少的存储空间，也保证了重要的数据及时存储。</span></li><li><span>探测器可设置清零值，在一些高精度高灵敏的设备可能出厂的时候默认值未必是0，需要设定清零值来表示初始值。</span></li><li><span>探测器可设置小数点，用于计算后的真实数据控制小数点点位显示，相当于除以10、除以100、除以1000，这样大部分的探测器数据直接通过小数点位设置控制真实换算后的值，极个别的需要特殊转换的可以在通信协议中约定。</span></li><li><span>探测器报警的类型支持多种，有些设备是高于某个值高报，低于某个值低报，而有些设备是在最小值最大值范围内是高报，低于最小值低报，高于最大值正常。这样可以分情况处理，涵盖各种报警类型。</span></li><li><span>原创数据导入、导出、打印机制，跨平台不依赖任何组件，瞬间导出数据。</span></li><li><span>导出到excel的记录支持所有excel、wps等表格文件版本，不依赖excel等软件。</span></li><li><span>高报颜色、低报颜色、正常颜色、默认值颜色等，都可以自由设置。</span></li><li><span>支持云端数据同步，将本地采集到的数据实时同步到云端。</span></li><li><span>支持网络转发和网络接收，网络接收开启后，软件从udp接收数据进行解析。网络转发支持多个目标IP，这样就实现了本地采集的软件，自由将数据转到客户端，随时查看采集到的数据。</span></li><li><span>自动记住用户最后停留的界面以及其他配置信息，重启后自动应用。</span></li><li><span>报警自动切换到对应的地图，探测器按钮闪烁，表格数据对应颜色显示。</span></li><li><span>双击探测器图标，弹出对应探测器详细信息，可以根据需要定制回控操作。</span></li><li><span>数据库支持多种，包括sqlite、mysql、sqlserver、postgresql、oracle、人大金仓等。</span></li><li><span>本地设备采集到的数据实时上传到云端，以便手机APP或者web等其他方式提取。</span></li><li><span>自带设备模拟工具，支持不同型号的多个设备数据模拟，支持串口和网络，同时还带数据库数据模拟，以便在没有设备的时候测试数据。</span></li><li><span>标准modbus协议，各种控制器类型、探测器类型、种类、符号等全部自定义，非常灵活和强大，通信协议示例数据非常完整，通用各种modbus协议系统，适用于各种应用场景接入。</span></li><li><span>同时集成了串口通信、网络通信、数据库通信、数据导入导出打印、通信协议解析、界面UI、全局换肤等众多组件和知识点，非常适合新手入门和进阶。</span></li><li><span>支持xp、win7、win10、、win11、linux、mac、树莓派、各种国产系统（UOS、中标麒麟、银河麒麟等）、嵌入式linux等系统。</span></li><li><span>注释完整，项目结构清晰，超级详细完整的使用开发手册，精确到每个代码文件的功能说明，不断持续迭代版本。</span></li></ol><h3 id='03-相关站点'><span>0.3 相关站点</span></h3><ol start='' ><li><span>国内站点：</span><a href='https://gitee.com/feiyangqingyun'><span>https://gitee.com/feiyangqingyun</span></a></li><li><span>国际站点：</span><a href='https://github.com/feiyangqingyun'><span>https://github.com/feiyangqingyun</span></a></li><li><span>个人主页：</span><a href='https://blog.csdn.net/feiyangqingyun'><span>https://blog.csdn.net/feiyangqingyun</span></a></li><li><span>知乎主页：</span><a href='https://www.zhihu.com/people/feiyangqingyun'><span>https://www.zhihu.com/people/feiyangqingyun</span></a></li><li><span>产品主页：</span><a href='https://blog.csdn.net/feiyangqingyun/article/details/97565652'><span>https://blog.csdn.net/feiyangqingyun/article/details/97565652</span></a></li><li><span>在线文档：</span><a href='https://feiyangqingyun.gitee.io/qwidgetdemo/iotsystem/'><span>https://feiyangqingyun.gitee.io/qwidgetdemo/iotsystem/</span></a></li><li><span>体验地址：</span><a href='https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A'><span>https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A</span></a><span> 提取码：o05q 文件名：bin_iotsystem.zip。</span></li><li><span>文章导航：</span><a href='https://qtchina.blog.csdn.net/article/details/121330922'><span>https://qtchina.blog.csdn.net/article/details/121330922</span></a></li></ol><h3 id='04-特别说明'><span>0.4 特别说明</span></h3><ol start='' ><li><span>主界面顶部为一级菜单导航，单击切换页面，软件的左侧为二级菜单导航。</span></li><li><span>在左侧菜单中，单击按钮可以切换到对应的页面。</span></li><li><span>软件会记住最后停留的页面，下次启动后自动切换。</span></li><li><span>发现数据不对或者有误，可以直接在设备调试界面查看具体的通信数据。</span></li><li><span>离线状态下双击设备面板或者设备按钮会主动立即重连一次，在线双击弹出详细信息。</span></li><li><span>本系统中的控制器相当于主设备，探测器相当于子设备节点。软件采集是和控制器之间通信。</span></li><li><span>系统采用纯QtWidget（非qml）编写，所有源码开放，并非有封装的库。</span></li><li><span>同时集成了数据库、多线程、串口通信、网络通信、协议解析、界面美化、UI布局等众多知识点。</span></li><li><span>未经本人许可不可将本项目源码扩散，如有发现本人将追究法律责任，谢谢配合。</span></li><li><span>高分屏缩放设置说明 </span><a href='https://qtchina.blog.csdn.net/article/details/124860909'><span>https://qtchina.blog.csdn.net/article/details/124860909</span></a><span>。</span></li></ol><h3 id='05-简易操作'><span>0.5 简易操作</span></h3><ol start='' ><li><span>第一步：从顶部一级菜单切换到系统设置，然后左侧二级菜单切换到端口管理。</span></li><li><span>第二步：添加好端口信息。</span></li><li><span>第三步：切换到控制器管理，添加好控制器信息。</span></li><li><span>第四步：切换到探测器管理，添加好探测器信息。</span></li><li><span>第五步：如果需要地图，则切换到地图管理，导入地图，默认已经有5张地图。</span></li><li><span>第六步：重启软件。</span></li></ol><h3 id='06-版本说明'><span>0.6 版本说明</span></h3><p><strong><span>V20220625</span></strong></p><ol start='' ><li><span>报警记录界面增加右键菜单选择全部、取消选中，和之前的批量删除一起。</span></li><li><span>测试批量删除sql语句in关键字在所有数据库中的表现，比如sqlite、mysql、postgres、sqlserver等全部测试通过。</span></li><li><span>优化报警邮件转发流程，过滤空报警信息只发送报警日志xls文件。</span></li><li><span>修复在postgresql数据库和oracle数据库下，QSqlTableModel对应setTable设置表名严格区分大小写的BUG。</span></li><li><span>大幅度优化mysql数据库分页查询效率，百万级别以上数据量下测试速度提升500倍+。</span></li><li><span>分页查询增加查询用时，每次翻页的查询都有用时计算。</span></li></ol><p><strong><span>V20220522</span></strong></p><ol start='' ><li><span>增加配置参数记录设备模拟工具是否已经通过主程序调用，已经打开了则不用重复打开。</span></li><li><span>修正数据库脚本文件，以便支持其他数据库，其他数据库全部测试过一遍。</span></li><li><span>增加各种数据库效果图，同步更新文档。</span></li><li><span>增加网络转发和云端数据库同步说明及效果图。</span></li><li><span>网络转发将分隔符改成字段数据用 , 分隔，行数据用 ; 分隔，最前面标识符用 | 分隔。</span></li><li><span>判断模拟工具是否打开算法再次改进，从命令行执行结果查看是否存在该程序。</span></li><li><span>所有数据库执行出错打印增加打印错误信息和对应的sql语句。</span></li><li><span>修复开启自动行数的时候，如果默认页面停留在其他页面，消息行数计算不准确的BUG。改成了默认采用左侧堆栈控件的高度作为参照标准，因为该控件永远显示，可以拿到正确的高度。</span></li><li><span>报警记录表格增加支持多选删除，可以批量删除选中的记录。</span></li><li><span>修复报警声音播放的BUG，在Qt5中默认播放首次设置的声音文件成功其余有杂音。</span></li><li><span>修复设备按钮报警颜色中低报和高报颜色搞反了的BUG。</span></li></ol><p><strong><span>V20220508</span></strong></p><ol start='' ><li><span>设备地图按钮增加报警颜色选项，低报黄色闪烁，高报红色闪烁，其他报警紫色闪烁，正常绿色。</span></li><li><span>修正低分辨率比如1366x768情况下默认配置文件窗体尺寸过大的问题。</span></li><li><span>修复设备面板在仪表盘样式情况下文字颜色没有和系统样式统一的BUG。</span></li><li><span>将设备面板统一到一个类，多种样式选择，普通样式、仪表样式等。</span></li><li><span>说明书中通信协议举例，重新整理，更丰富更完整。</span></li><li><span>消息栏改成0表示自动设置行数，100表示设置0行，其他表示选择的行数。</span></li><li><span>将面板样式切换直接移到主界面，方便直接切换立即应用。</span></li><li><span>删减合并一些冗余的代码。</span></li><li><span>修复离线后仪表盘的值没有清零的BUG。</span></li><li><span>修复有部分权限页面控制不准的BUG。</span></li><li><span>新增自启动设备模拟工具配置参数，可以在系统设置中功能激活启用。</span></li><li><span>将模拟工具启动放在主窗体加载完成后，之前的main函数中不妥当，会导致用户还没登录就运行了设备模拟工具。</span></li><li><span>探测器节点信息，系统设置新增排序规则，可以按照位号排序，或者种类+位号等方式。</span></li><li><span>增加在win以外的其他系统，自动new出来设备模拟工具。</span></li><li><span>改进默认地图算法，取第一个有背景地图的设备的图片作为默认图片，可能默认图片不存在则取图片列表中的第一张。</span></li></ol><p><strong><span>V20220428</span></strong></p><ol start='' ><li><span>将项目统一命名为iotsystem，对应设备模拟工具iottool。</span></li><li><span>将多个模块提炼成通用模块，比如用户登录退出、数据库设置、用户管理等，这样可以和其他系统完全公用模块。</span></li><li><span>统一调整项目模块，统一规划。</span></li><li><span>重新截图，重新编写说明书和开发使用手册。</span></li><li><span>权限控制增加用户管理、组态设计等，替换之前备用的模块A、模块B。</span></li><li><span>将用户管理、组态设计、设备调试等模块移动到其他设置大类，方便管理。</span></li><li><span>修复非最大化界面，拖动设备按钮会触发界面移动并且乱跳的BUG。</span></li><li><span>修复本地电脑开启网络代理的情况下，网络链接本地IP地址报错提示 The proxy type is invalid for this operation 的BUG。</span></li><li><span>模拟工具增加一键复位和一键报警按钮，用于设置没有报警的值和报警的值。</span></li><li><span>修复Qt6中报警后重复触发报警声音会崩溃的BUG。</span></li><li><span>统一梳理所有数据库字段长度，留有足够的余地。</span></li><li><span>修复设备面板在低报高报互相切换状态的时候报警颜色不正确的BUG。</span></li></ol><p><strong><span>V20190712</span></strong></p><ol start='' ><li><span>控制器型号+探测器型号+气体种类+气体符号改成表格存储，新增探测器数量字段。</span></li><li><span>当节点数量小于列数时候会宽度变宽的BUG。</span></li><li><span>新增阿里云数据库同步，数据库采集模式会将数据库数据实时同步到阿里云。</span></li></ol><p><strong><span>V20190624</span></strong></p><ol start='' ><li><span>nodeinfo表新增nodezero字段，用于存储消零值，小于该值则显示为0，大于则显示真实值。</span></li><li><span>alarmlog表增加confirmuser、confirmtime、confirmcontent三个字段，存储报警记录的确认用户、确认时间、确认内容。</span></li><li><span>新增了数据库读取模式，用于数据库采集显示数据。</span></li><li><span>修复了Qt5.10版本以上，数据清理线程提示不能运行的BUG。不能在线程中用主线程创建的数据库。</span></li><li><span>改进了部分代码。</span></li><li><span>模拟器新增数据库模拟。</span></li><li><span>配置文件新增模拟器的配置信息。</span></li><li><span>修复表格中设置了单独的文字颜色，在选中时会被覆盖的BUG。</span></li><li><span>新增报警右下角弹框。可以配置文件更改是否开启以及显示多久，默认开启。</span></li><li><span>新增报警记录鼠标右键删除记录，支持多选批量删除。</span></li><li><span>设备表格，按照气体种类升序+位号升序排列，以前是按照位号。</span></li><li><span>控制器对应的最大探测器数量，已禁用，直接选择好探测器类型自动设置。</span></li></ol><h2 id='1-用户登录退出'><span>1 用户登录退出</span></h2><h3 id='11-用户登录'><span>1.1 用户登录</span></h3><p><span> </span><img src="snap/1-1-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/1-1-2.jpg" referrerpolicy="no-referrer"></p><p><span>系统启动后，首先会弹出用户登录界面，从用户姓名的下拉框选择用户名，然后输入密码（默认用户名密码都是admin），单击登录按钮，密码正确则会进入到系统主界面，错误会弹出提示，错误超过三次自动关闭，需要重新打开软件。</span></p><p><span>在登录界面可以勾选是否记住密码，是否自动登录，如果勾选了记住密码，则下次启用软件会自动填入最后用户的密码，勾选了自动登录（以最后的用户信息作为当前登录用户）则启动后直接进入主界面。如果开启了自动登录，不会弹出登录界面，可以在系统设置中关闭自动登录和记住密码。</span></p><h3 id='12-用户退出'><span>1.2 用户退出</span></h3><p><span> </span><img src="snap/1-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>在主界面单击右上角的关闭按钮，会弹出用户退出界面，需要输入密码验证防止误关闭，会自动填入登录的用户名，密码输入正确才会退出软件。用户登录和退出都内置了超级密码a防止管理员忘记密码。</span></p><h2 id='2-系统设置'><span>2 系统设置</span></h2><h3 id='21-基本设置'><span>2.1 基本设置</span></h3><p><span> </span><img src="snap/2-1-0.jpg" referrerpolicy="no-referrer"></p><h4 id='211-常规设置'><span>2.1.1 常规设置</span></h4><p><span> </span><img src="snap/2-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>基本设置中有部分参数的切换会自动重启应用。</span></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>开机运行：开启以后自动随着系统启动运行，默认开启。</span></li><li><span>自动登录：开启以后会自动以最后登录的用户信息登录到系统，默认关闭。</span></li><li><span>记住密码：开启以后会自动填入最后登录的用户信息到登录窗体，默认关闭。</span></li><li><span>中文标题：软件左上角标题栏的中文标题，改动立即应用。</span></li><li><span>英文标题：软件左上角标题栏的英文标题，改动立即应用。</span></li><li><span>版权所有：当前软件版权所有的公司，显示在软件的底部信息栏中。</span></li><li><span>调试日志：开启后会将打印日志输出到日志文件，默认关闭，日志文件存放在可执行文件夹下的log目录下。</span></li><li><span>运行时间：开启后会实时记录系统的运行时间，记录当前软件启动后运行了多久，运行时间文件存放在可执行文件夹下的log目录下。</span></li><li><span>工作模式：默认设备采集，可选数据库采集、数据库读取、设备采集2等，一般都是特殊定制需求的在这里切换工作模式。</span></li><li><span>导航样式：用于选择顶部导航栏和左侧导航栏的样式，上侧+左侧表示顶部导航栏上侧样式（图标在上面，文字在下面），左侧导航栏左侧样式（图标在左侧，文字在右侧）。</span></li><li><span>界面样式：系统自带17套皮肤，可以在这里自动换肤，默认视频黑。</span></li><li><span>软件图标：自动从logo文件夹读取，可以自行选择对应的logo文件。</span></li><li><span>报警声音：开启后当探测器报警后，会播放报警声音，默认开启。</span></li><li><span>播放次数：播放报警声音的次数，默认1次。</span></li><li><span>警情行数：主界面运行监测左侧显示报警信息的最大行数。新警情自动追加在最前面。0表示自动根据尺寸填充，100表示禁用。</span></li><li><span>自动确认：开启后自动确认警情存入报警记录，默认开启。</span></li><li><span>设备列数：设备监控主界面设备面板的列数。</span></li><li><span>记录行数：在数据查询的表格中，显示的记录的行数。</span></li></ol><p><strong><span>工作模式</span></strong></p><ol start='' ><li><span>设备采集：本地直接采集网络和串口过来的数据，每个数据位2字节表示一个含义。</span></li><li><span>数据库采集：定时器读取数据库表NodeData，具体字段含义见数据库表说明。</span></li><li><span>数据库采集2：和数据库采集逻辑一样，就是具体的报警标志位含义不一样。</span></li><li><span>设备采集2：用户定制的一套解析协议，和上面设备采集的区别是收发协议两样，带有电源、报警标志位，每个探测器4寄存器=8字节。</span></li></ol><ul><li><span>设备采集模式 nodeStatus 0-低报 1-低报恢复 2-高报 3-高报恢复 5-其他报警 6-其他报警恢复</span></li><li><span>数据库采集模式 nodeStatus 0-离线  1-在线  2-低报  3-高报</span></li><li><span>数据库采集2模式 nodeStatus 0-离线  1-正常  2-报警  3-高报  4-失效</span></li><li><span>设备采集2模式 nodeStatus 0-预热中 1-工作中 2-低限报警 3-高限报警 4-传感器故障 7-探测器离线</span></li></ul><h4 id='212-本地数据库设置'><span>2.1.2 本地数据库设置</span></h4><p><span> </span><img src="snap/2-1-2.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>远程同步：开启后将会启用云端数据同步功能，将本地数据实时同步到远程数据库中。</span></li><li><span>主机类型：和本地数据库设置一样，可选多种。</span></li><li><span>数据库名：对应数据库的数据库名称，一个数据库系统中可以有多个数据库实例。</span></li><li><span>主机地址：数据库所在的网络地址，可以是IP地址或者网址。</span></li><li><span>通信端口：数据库开放通信的端口，不同数据库默认端口不同，比如mysql是3306，postgres是5432，sqlserver是1433。</span></li><li><span>用户名称：登录到网络数据库对应的用户名称，所有的网络型数据库都需要用户认证。sqlite是文件型数据库一般不需要认证。</span></li><li><span>用户密码：登录到网络数据库对应的用户密码，所有的网络型数据库都需要用户认证。sqlite是文件型数据库一般不需要认证。</span></li><li><span>连接测试：单击后主动连接一次当前填入的数据库信息，连接成功与失败都会弹框提示。</span></li><li><span>初始数据：单击后会执行sql脚本文件，重置数据库，会将原来的数据一并清空。务必记得只有需要的时候才执行。</span></li></ol><p><strong><span>其他说明</span></strong></p><ol start='' ><li><span>默认提供了数据库脚本文件（拓展名sql结尾的文件）。</span></li><li><span>单击初始化数据按钮可以对整个数据库进行新建和重置，相当于恢复出厂。</span></li><li><span>系统支持多种数据库，默认sqlite（Qt内置的数据库，无需安装），可选mysql、postgresql、oracle、人大金仓等。</span></li><li><span>具体还需要对应Qt版本有数据库插件支持，没有插件支持可以自行编译对应缺失的插件比如mysql，也可选直接通过万能的ODBC来连接。</span></li><li><span>除了sqlite数据库外，其余数据库都需要输入数据库名称、主机地址、通信端口、用户名称、用户密码信息，输入好以后可以单击连接测试按钮测试下是否正常。</span></li><li><span>默认提供的是mysql的动态库libmysql.dll，需要放到可执行文件同一目录，严格区分32位和64位的动态库。</span></li></ol><pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="cpp" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="cpp"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 9.51471px; left: 42.9832px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 35px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><span><span>​</span>x</span></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: -34.9916px; width: 35px;"></div><div class="CodeMirror-gutter-wrapper CodeMirror-activeline-gutter" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">1</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//数据库类型枚举</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">2</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">enum</span> <span class="cm-def">DbType</span> {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">3</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_ODBC</span> <span class="cm-operator">=</span> <span class="cm-number">0</span>, &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment">//odbc数据源</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">4</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_Sqlite</span> <span class="cm-operator">=</span> <span class="cm-number">1</span>, &nbsp; &nbsp; &nbsp;<span class="cm-comment">//sqlite数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">5</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_MySql</span> <span class="cm-operator">=</span> <span class="cm-number">2</span>, &nbsp; &nbsp; &nbsp; <span class="cm-comment">//mysql数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">6</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_PostgreSQL</span> <span class="cm-operator">=</span> <span class="cm-number">3</span>, &nbsp;<span class="cm-comment">//postgresql数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">7</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_SqlServer</span> <span class="cm-operator">=</span> <span class="cm-number">4</span>, &nbsp; <span class="cm-comment">//sqlserver数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">8</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_Oracle</span> <span class="cm-operator">=</span> <span class="cm-number">5</span>, &nbsp; &nbsp; &nbsp;<span class="cm-comment">//oracle数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">9</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_KingBase</span> <span class="cm-operator">=</span> <span class="cm-number">6</span>, &nbsp; &nbsp;<span class="cm-comment">//人大金仓数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">10</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">DbType_Other</span> <span class="cm-operator">=</span> <span class="cm-number">255</span> &nbsp; &nbsp; &nbsp;<span class="cm-comment">//其他数据库</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">11</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">};</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">12</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//自动切换默认数据库端口</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">DbHelper::getDbDefaultInfo</span>(<span class="cm-keyword">const</span> <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">dbType</span>, <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">hostPort</span>,</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">userName</span>, <span class="cm-variable">QString</span> <span class="cm-operator">&amp;</span><span class="cm-variable">userPwd</span>)</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"MYSQL"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"3306"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"root"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">20</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"root"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">21</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"SQLSERVER"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">22</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"1433"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">23</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"sa"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">24</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">25</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"POSTGRESQL"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">26</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"5432"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">27</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"postgres"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">28</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">29</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"ORACLE"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">30</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"1521"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">31</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"system"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">32</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">33</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  } <span class="cm-keyword">else</span> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"KINGBASE"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">34</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"54321"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">35</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"SYSTEM"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">36</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"123456"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">37</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp;  }</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">38</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 875px;"></div><div class="CodeMirror-gutters" style="height: 875px;"><div class="CodeMirror-gutter CodeMirror-linenumbers" style="width: 34px;"></div></div></div></div></pre><h4 id='213-云端数据库同步'><span>2.1.3 云端数据库同步</span></h4><p><span> </span><img src="snap/2-1-3.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>远程同步：开启后将会启用云端数据同步功能，将本地数据实时同步到远程数据库中。</span></li><li><span>主机类型：和本地数据库设置一样，可选多种。</span></li><li><span>数据库名：对应数据库的数据库名称，一个数据库系统中可以有多个数据库实例。</span></li><li><span>主机地址：数据库所在的网络地址，可以是IP地址或者网址。</span></li><li><span>通信端口：数据库开放通信的端口，不同数据库默认端口不同，比如mysql是3306，postgres是5432，sqlserver是1433。</span></li><li><span>用户名称：登录到网络数据库对应的用户名称，所有的网络型数据库都需要用户认证。sqlite是文件型数据库一般不需要认证。</span></li><li><span>用户密码：登录到网络数据库对应的用户密码，所有的网络型数据库都需要用户认证。sqlite是文件型数据库一般不需要认证。</span></li><li><span>连接测试：单击后主动连接一次当前填入的数据库信息，连接成功与失败都会弹框提示。</span></li><li><span>初始数据：单击后会执行sql脚本文件，重置数据库，会将原来的数据一并清空。务必记得只有需要的时候才执行。</span></li></ol><h4 id='214-日志设置'><span>2.1.4 日志设置</span></h4><p><span> </span><img src="snap/2-1-4.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>报警记录：报警记录存储最大数量，超过会自动清理，相当于永远存储最近的记录，把早期数据清空，留给最新的数据，节约空间。</span></li><li><span>运行记录：运行记录存储最大数量，超过会自动清理，相当于永远存储最近的记录，把早期数据清空，留给最新的数据，节约空间。</span></li><li><span>操作记录：操作记录存储最大数量，超过会自动清理，相当于永远存储最近的记录，把早期数据清空，留给最新的数据，节约空间。</span></li><li><span>记录排序：在报警记录查询界面中，按照何种方式排序，默认按照时间降序，相当于最新的记录在最前面。</span></li><li><span>报警弹框：报警触发后在右下角弹框信息停留时间，0秒表示一直停留直到手动关闭，10000秒表示不弹出。</span></li><li><span>小数点位：设备采集到的数据，最后按照几位小数点显示。</span></li></ol><h4 id='215-网络转发设置'><span>2.1.5 网络转发设置</span></h4><p><span> </span><img src="snap/2-1-5.jpg" referrerpolicy="no-referrer"></p><p><span>网络转发的功能，是用来将本地的采集的所有设备的数据，通过UDP协议转发到指定的IP和端口，对方只要开启网络接收即可查看到设备的实时运行数据。网络转发和网络接收不能同时开启，本地负责采集的软件开启网络转发，远程需要查看数据的电脑开启网络接收，转发的端口和接收的端口必须保持一致，支持多个IP，中间用英文的分号 ; 隔开。单击同步数据的按钮会将本地的端口+设备+节点信息传送到接收端，不需要手动设置。这样就保证了本地的信息和远程的信息完全一致。远程的IP必须保证可达，比如ping的通。</span></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>网络转发：开启后会将本地的数据通过udp协议发到指定的网络地址和端口。</span></li><li><span>IP及端口：网络转发要去达的网络地址和端口，用英文冒号 : 隔开。</span></li><li><span>网络接收：开启后将采用接收端形式运行，接收转发过来的设备数据作为采集源。</span></li><li><span>接收端口：网络接收端口。</span></li><li><span>同步数据：开启网络转发后，单击该按钮，会将本地的端口信息、控制器信息、探测器信息发送到远端，这样远端接收到数据后不用手动添加。</span></li></ol><h4 id='216-告警短信转发'><span>2.1.6 告警短信转发</span></h4><p><span> </span><img src="snap/2-1-6.jpg" referrerpolicy="no-referrer"></p><p><span>当探测器发生报警后，如果开启了短信告警，会将报警信息以短信的形式发送到预先设定的接收者的手机号码上，短信内容格式为：位号: AT400001  控制器: 控制器A  探测器: 探测器A  触发值: 70.8 PPM  类型: 浓度上限报警  时间: 2019-01-05 12:12:12。需要本地发短信的硬件支持。</span></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>串口名称：短信猫设备接入的串口号。</span></li><li><span>波 特 率：短信猫设备通信所使用的波特率。</span></li><li><span>接收号码：接收者的手机号码，可以填写多个，中间用英文的分号 ; 隔开。</span></li><li><span>发送间隔：短信发送的间隔，默认10000表示不开启，0表示实时发送。</span></li><li><span>测试短信：单击该按钮会立即发送一条测试短信到接收者手机用于测试功能是否正常。</span></li></ol><h4 id='217-告警邮件转发'><span>2.1.7 告警邮件转发</span></h4><p><span> </span><img src="snap/2-1-7.jpg" referrerpolicy="no-referrer"></p><p><span>当探测器发生报警后，如果开启了邮件转发告警，会将报警信息以邮件的形式发送到预先设定的接收者的邮箱中，邮件内容格式为：位号: AT400001  控制器: 控制器A  探测器: 探测器A  触发值: 70.8 PPM  类型: 浓度上限报警  时间: 2019-01-05 12:12:12。后期会将警情统计的报表数据以excel表格的形式发送到接收者邮箱。如果发现邮箱登录失败等，请先在邮箱后台设置开启smtp和pop3。</span></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>发件邮箱：发件人的邮箱地址，必须保证该邮箱开启过POP3。</span></li><li><span>发件密码：发件人的邮箱的密码，会以加密的形式存储在配置文件。</span></li><li><span>接收邮箱：接收者的邮箱地址，支持多个，用英文的分号 ; 隔开。</span></li><li><span>发送间隔：邮件发送的间隔，默认10000表示不开启，0表示实时发送。</span></li><li><span>测试邮件：单击该按钮会立即发送一条测试邮件到接收者邮箱用于测试功能是否正常。</span></li></ol><h4 id='218-系统时间设置'><span>2.1.8 系统时间设置</span></h4><p><span> </span><img src="snap/2-1-8.jpg" referrerpolicy="no-referrer"></p><p><span>用来设置本地电脑的系统时间，为什么需要这个设置，因为软件很可能在嵌入式linux上运行，需要手动设置时间。</span></p><h4 id='219-功能激活'><span>2.1.9 功能激活</span></h4><p><span> </span><img src="snap/2-1-9.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>表格联动：开启后在数据监控的表格中会自动实时显示采集的设备数据。</span></li><li><span>面板联动：开启后在设备面板对应的设备会自动显示采集的设备数据。</span></li><li><span>按钮联动：开启后在地图监控上对应的按钮会自动显示采集的设备数据。</span></li><li><span>设备地图：开启后会显示设备地图模块，默认关闭，大部分场景用不上，只需要表格展示数据，最高效。</span></li></ol><h4 id='2110-颜色设置'><span>2.1.10 颜色设置</span></h4><p><span> </span><img src="snap/2-1-10.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>离线颜色：探测器离线后对应文字显示的颜色。</span></li><li><span>高报颜色：探测器发生上限报警（高报）后对应文字显示的颜色。</span></li><li><span>低报颜色：探测器发生下限报警（低报）后对应文字显示的颜色。</span></li><li><span>正常颜色：探测器运行正常时对应文字显示的颜色。</span></li><li><span>曲线背景：探测器实时曲线界面背景颜色。</span></li><li><span>曲线文字：探测器实时曲线界面文字颜色。</span></li><li><span>曲线颜色：探测器实时曲线界面曲线的颜色。</span></li><li><span>待定颜色：目前备用的颜色。</span></li></ol><h3 id='22-端口管理'><span>2.2 端口管理</span></h3><p><span> </span><img src="snap/2-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统支持串口接入和网络接入两种方式，对应的端口需要提前设置，后期可能还会新增mqtt等方式，选择不同的协议类型即可。</span></p><p><strong><span>字段说明</span></strong></p><ol start='' ><li><span>端口编号：端口的编号，从1开始。</span></li><li><span>端口名称：端口的别名，方便记忆。</span></li><li><span>协议类型：默认Modbus_Com为串口通信，TCP通信选择Modbus_Tcp_Rtu。</span></li><li><span>串 口 号：如果用的是串口通信，这里填入串口号即可。</span></li><li><span>波 特 率：串口通信使用的波特率。</span></li><li><span>IP 地 址：设备的IP地址。</span></li><li><span>通讯端口：该设备网络通信所使用的端口，默认502，即modbus通信的端口。</span></li><li><span>采集周期：该通讯处理中对每个控制器轮询的间隔时间。单位秒，如果要0.2s=200毫秒则填0.2即可，默认浮点数处理。</span></li><li><span>通讯超时：该通讯处理中大于几次未收到回应消息则判断为离线，默认3次。</span></li><li><span>重连时间：如果某个设备离线状态，最大多长时间重新读取一次，默认60秒。</span></li></ol><h4 id='221-端口添加'><span>2.2.1 端口添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='222-端口删除'><span>2.2.2 端口删除</span></h4><p><span>如果要删除某个端口信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='223-端口清空'><span>2.2.3 端口清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='224-端口信息导入'><span>2.2.4 端口信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='225-端口信息导出'><span>2.2.5 端口信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。　　</span></p><h4 id='226-端口信息打印'><span>2.2.6 端口信息打印</span></h4><p><span> </span><img src="snap/2-2-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='227-导出到excel'><span>2.2.7 导出到Excel</span></h4><p><span> </span><img src="snap/2-2-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h3 id='23-控制器管理'><span>2.3 控制器管理</span></h3><p><span> </span><img src="snap/2-3-1.jpg" referrerpolicy="no-referrer"></p><p><strong><span>字段说明</span></strong></p><ol start='' ><li><span>控制器编号：控制器的编号，从1开始。</span></li><li><span>通 讯 端口：通讯所采用的通讯端口名称，和端口管理中的端口名称一致。</span></li><li><span>控制器名称：控制器的别名，以便记忆。</span></li><li><span>控制器地址：控制器的地址，最大255。</span></li><li><span>控制器型号：控制器的型号，不一样的控制器可能通信的协议不一致。</span></li><li><span>探测器数量：该控制器下面挂载的探测器的数量，必须和真实安装的数量完全一致。</span></li></ol><h4 id='231-控制器添加'><span>2.3.1 控制器添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='232-控制器删除'><span>2.3.2 控制器删除</span></h4><p><span>如果要删除某个控制器信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='233-控制器清空'><span>2.3.3 控制器清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='234-控制器信息导入'><span>2.3.4 控制器信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='235-控制器信息导出'><span>2.3.5 控制器信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。　　</span></p><h4 id='236-控制器信息打印'><span>2.3.6 控制器信息打印</span></h4><p><span> </span><img src="snap/2-3-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='237-导出到excel'><span>2.3.7 导出到Excel</span></h4><p><span> </span><img src="snap/2-3-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h3 id='24-探测器管理'><span>2.4 探测器管理</span></h3><p><span> </span><img src="snap/2-4-1.jpg" referrerpolicy="no-referrer"></p><p><strong><span>字段说明</span></strong></p><ol start='' ><li><span>编    号：节点的编号，从1开始。</span></li><li><span>位    号：探测器的位置编号，用于唯一标识一个探测器。</span></li><li><span>控 制 器：对应挂载的主设备名称。</span></li><li><span>探 测 器：探测器的名称，方便记忆，可以填写地理位置。</span></li><li><span>地    址：探测器对应在控制器的编号索引。</span></li><li><span>型    号：探测器的型号，从下拉框选择。</span></li><li><span>气体种类：探测器对应采集的气体的种类。</span></li><li><span>气体型号：探测器对应采集气体的型号。</span></li><li><span>上 限 值：报警的上限值。</span></li><li><span>下 限 值：报警的下限值</span></li><li><span>最 大 值：最大的警戒值，超过该值则显示为该值。</span></li><li><span>消    零：最小的警戒值，小于该值则显示0，大于显示真实值。</span></li><li><span>量    程：假设量程0.25则 实际数=模拟量/4000x量程 模拟量就是采集的值。</span></li><li><span>状    态：默认启用，当某个探测器未接时候可以选择禁用。</span></li><li><span>声    音：报警后对应的声音文件。</span></li><li><span>地    图：探测器所位于的地图文件。</span></li><li><span>存    储：探测器记录存储的周期，单位分钟。即隔多久存储一次记录到本地。</span></li><li><span>小 数 点：计算解析数据的数据位对应的小数点位数。</span></li><li><span>报警延时：报警后，延时多久处理，以便过滤数据抖动偏差造成的误报。默认0。</span></li><li><span>报警类型：HH LL HL。</span></li><li><span>X坐 标：探测器位于地图上的X坐标。</span></li><li><span>Y坐 标：探测器位于地图上的Y坐标。</span></li></ol><p><strong><span>报警类型</span></strong></p><ul><li><span>根据设定的不同的报警类型处理，假定上限值100，下限值25。</span></li><li><span>HH表示超过25是低报，超过100是高报，低于25正常。</span></li><li><span>HL表示低于25是低报，超过100是高报，25到100之间正常。</span></li><li><span>LL表示低于25是高报，低于100是低报，大于100正常。</span></li></ul><h4 id='241-探测器添加'><span>2.4.1 探测器添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='242-探测器删除'><span>2.4.2 探测器删除</span></h4><p><span>如果要删除某个探测器信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='243-探测器清空'><span>2.4.3 探测器清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='244-探测器信息导入'><span>2.4.4 探测器信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='245-探测器信息导出'><span>2.4.5 探测器信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。　　</span></p><h4 id='246-探测器信息打印'><span>2.4.6 探测器信息打印</span></h4><p><span> </span><img src="snap/2-4-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='247-导出到excel'><span>2.4.7 导出到Excel</span></h4><p><span> </span><img src="snap/2-4-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h3 id='25-报警联动'><span>2.5 报警联动</span></h3><p><span> </span><img src="snap/2-5-1.jpg" referrerpolicy="no-referrer"></p><p><span>在报警联动设置中，可以设置每个位号报警后，对应的继电器联动，支持探测器串口和新独立的串口（如果是和探测器并用的串口则不会重新打开串口，直接用原有的串口发数据联动，如果是新的串口则会重新打开串口），模块地址为继电器板子的地址，联动地址集合为需要联动报警的位，支持多个，多对多关系，一个探测器报警可以联动多个联动模块上的多个继电器地址，中间丨杠隔开。</span></p><p><strong><span>字段说明</span></strong></p><ol start='' ><li><span>位置编号：下拉选择，从探测器信息表取，表示哪个位置的探测器报警。</span></li><li><span>串 口 号：串口号，可以是之前端口信息中的串口，会自动检测切换。</span></li><li><span>波 特 率：报警端口转发串口对应的波特率，默认9600。</span></li><li><span>模块地址：对应联动模块的地址，挂在总线上的联动模块的唯一地址，该模块专门用来做继电器联动。</span></li><li><span>联动地址：联动模块上有一排继电器地址，对应报警后，可以触发联动一个或者多个继电器，需要哪个地址就填哪些地址。</span></li><li><span>启    用：可以动态关闭不需要的联动信息，但是不删除，这样只需要这里取消启用即可，而不是删除，不然又要重新添加。</span></li></ol><h4 id='251-联动添加'><span>2.5.1 联动添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='252-联动删除'><span>2.5.2 联动删除</span></h4><p><span>如果要删除某个联动信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='253-联动清空'><span>2.5.3 联动清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='254-联动信息导入'><span>2.5.4 联动信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='255-联动信息导出'><span>2.5.5 联动信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。　　</span></p><h4 id='256-联动信息打印'><span>2.5.6 联动信息打印</span></h4><p><span> </span><img src="snap/2-5-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='257-导出到excel'><span>2.5.7 导出到Excel</span></h4><p><span> </span><img src="snap/2-5-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h3 id='26-类型设置'><span>2.6 类型设置</span></h3><p><span> </span><img src="snap/2-6-1.jpg" referrerpolicy="no-referrer"></p><p><strong><span>参数说明</span></strong></p><ul><li><span>本表格中的数据并不是严格的对应关系。</span></li><li><span>其中控制器信号、探测器数量是一对，其余全部独立。</span></li><li><span>用来在系统设置中对应下拉框中的信息。</span></li><li><span>这样就非常灵活，用户后期增加了新的产品直接在这里添加好就行，其他地方都是自动下拉选择。</span></li></ul><h4 id='261-类型添加'><span>2.6.1 类型添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='262-类型删除'><span>2.6.2 类型删除</span></h4><p><span>如果要删除某个类型信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。</span></p><h4 id='263-类型清空'><span>2.6.3 类型清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='264-类型信息导入'><span>2.6.4 类型信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='265-类型信息导出'><span>2.6.5 类型信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。　　</span></p><h4 id='266-类型信息打印'><span>2.6.6 类型信息打印</span></h4><p><span> </span><img src="snap/2-6-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='267-导出到excel'><span>2.6.7 导出到Excel</span></h4><p><span> </span><img src="snap/2-6-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h2 id='3-其他设置'><span>3 其他设置</span></h2><h3 id='31-用户管理'><span>3.1 用户管理</span></h3><p><span> </span><img src="snap/3-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>用户管理是后面增加的一个模块，用于设置不同的用户不同的类型+权限，可以细分到每个模块的权限，勾选表示具有该权限，内置了7种权限选择，后期还可以在此基础上增加其他权限等。</span></p><h4 id='311-用户添加'><span>3.1.1 用户添加</span></h4><p><span>单击添加按钮，会自动规则生成默认的信息，直接表格中修改即可，修改好以后单击保存按钮保存所有的信息。</span></p><h4 id='312-用户删除'><span>3.1.2 用户删除</span></h4><p><span>如果要删除某个用户信息，需要先选中该行，然后单击删除按钮，删除后会自动保存。不允许删除内置的admin用户。</span></p><h4 id='313-用户清空'><span>3.1.3 用户清空</span></h4><p><span>单击清空按钮会对整个表进行清空操作，清空后数据不能恢复，慎用。</span></p><h4 id='314-用户信息导入'><span>3.1.4 用户信息导入</span></h4><p><span>单击导入按钮，可以选择之前导出的csv格式的文件导入数据。</span></p><h4 id='315-用户信息导出'><span>3.1.5 用户信息导出</span></h4><p><span>单击导出按钮，将表格数据导出到csv格式的文件，用户可以打开文件编辑，然后再次导入，这样可以作为简易的备份机制使用，也可将繁琐的基础数据录入交给小姑娘去做。</span></p><h4 id='316-用户信息打印'><span>3.1.6 用户信息打印</span></h4><p><span> </span><img src="snap/3-1-6.jpg" referrerpolicy="no-referrer"></p><p><span>单击打印按钮可以将表格中的内容打印出来，打印前会弹出打印预览界面，可以自行做边距的调整等，可以查看等待打印的内容，翻页切换。</span></p><h4 id='317-导出到excel'><span>3.1.7 导出到Excel</span></h4><p><span> </span><img src="snap/3-1-7.jpg" referrerpolicy="no-referrer"></p><p><span>单击导出按钮可以将表格中的内容导出到excel表格，独创的excel导出数据算法，极速导出，支持任意系统，无依赖。</span></p><h4 id='318-权限验证'><span>3.1.8 权限验证</span></h4><p><span> </span><img src="snap/3-1-8-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/3-1-8-2.jpg" referrerpolicy="no-referrer"></p><p><span>假设设置了用户没有系统设置和删除记录的权限，则关闭系统的时候会弹出错误信息提示当前用户没有权限。</span></p><h3 id='32-地图管理'><span>3.2 地图管理</span></h3><p><span> </span><img src="snap/3-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>在地图管理中，可以导入和删除地图。</span></p><h3 id='33-位置调整'><span>3.3 位置调整</span></h3><p><span> </span><img src="snap/3-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>位置调整中，可以拖动探测器到正确的位置，右侧单击地图切换可以看到对应的该地图对应的探测器，全部位置调整好之后，单击右下角保存按钮即可，会立即应用。</span></p><h3 id='34-组态设计'><span>3.4 组态设计</span></h3><p><span> </span><img src="snap/3-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>组态设计模块中提供的是简单的示例，演示如何加载自定义控件动态库、将控件拖曳到背景地图上，配置好对应控件的属性，可定义用户属性，可导出控件的配置信息到xml文件，并支持导入xml文件自动加载上次保存的控件配置信息。目前是一个简单的组态雏形，等后期架构好如何应用再重写整个模块。</span></p><p><strong><span>本系统默认不包括里面控件的源码，提供动态库的形式使用，如果还想学习自定义控件大全的源码（目前共202个控件卖700元），需要额外单独购买。</span></strong></p><h3 id='35-设备调试'><span>3.5 设备调试</span></h3><p><span> </span><img src="snap/3-5-1.jpg" referrerpolicy="no-referrer"></p><p><span>可以自行选择通讯端口+设备名称进行数据的过滤，可查看所有的通信数据。不同收发数据不同颜色，还可以指定关键字过滤数据，每个收发数据都有对应的中文解释。能够很方便的对运行中的系统查看设备数据，规避是下位机还是上位机问题扯皮的事情。</span></p><h2 id='4-设备监控'><span>4 设备监控</span></h2><p><span> </span><img src="snap/4-0-1.jpg" referrerpolicy="no-referrer"></p><p><span>设备监控界面主要包括4个模块，分别是数据监控、设备面板、地图监控、曲线监控，设备的实时数据可以同时反应到四个模块上面，相当于以4种不同的表现形式展现采集到的数据。</span></p><p><strong><span>模式说明</span></strong></p><ul><li><span>数据监控：表格形式一行行展示数据。</span></li><li><span>设备面板：每个探测器都是个独立的一个面板展示数据和信息。</span></li><li><span>地图监控：设备按钮放在对应地图上，长条状显示数据和符号单位。</span></li><li><span>曲线监控：对每个设备过滤曲线显示采集到的数据。</span></li><li><span>设备报警后，如果设置了报警弹窗，则右下角都会弹出对应的报警信息。</span></li><li><span>设备报警后，对应表格行、设备面板、地图按钮等都会突出颜色显示。</span></li></ul><h3 id='41-数据监控'><span>4.1 数据监控</span></h3><p><span> </span><img src="snap/4-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>本页面会是使用频率最高的页面，默认就是停留在本页面实时查看所有探测器的数据。左侧为警情信息栏，分别显示时间、位号、报警值。如果有探测器报警，则消息自动追加到最前面。</span>
<span>表格依次显示序号、位号、控制器名称、控制器型号、探测器名称、探测器型号、气体种类、浓度值、气体符号。</span></p><h3 id='42-设备面板'><span>4.2 设备面板</span></h3><p><strong><span>面板说明</span></strong></p><ol start='' ><li><span>探测器作为一个个独立的设备面板控件。</span></li><li><span>有多少个探测器就会生成多少个面板，放在面板容器中。</span></li><li><span>可以在系统设置中选择设备列数，按照该设备列数来排列，超过会自动产生滚动条拖动查看。</span></li><li><span>报警后整个设备面板会突出颜色显示比如高报是红色、低报是黄色等。</span></li><li><span>双击探测器面板，会跳转到该探测器的详细信息界面，在该界面上后期可以按照实际用户需求定制回控操作。</span></li><li><span>面板有多种样式可供选择，比如普通样式、仪表样式。可直接在右侧切换立即运用。</span></li></ol><h4 id='421-普通样式'><span>4.2.1 普通样式</span></h4><p><span> </span><img src="snap/4-2-1.jpg" referrerpolicy="no-referrer"></p><h4 id='422-仪表样式'><span>4.2.2 仪表样式</span></h4><p><img src="snap/4-2-2.jpg" referrerpolicy="no-referrer"></p><h4 id='423-仪表样式2'><span>4.2.3 仪表样式2</span></h4><p><img src="snap/4-2-3.jpg" referrerpolicy="no-referrer"></p><h3 id='43-地图监控'><span>4.3 地图监控</span></h3><p><span> </span><img src="snap/4-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>本页面以地图的形式显示所有探测器，右侧单击对应地图可以手动切换地图，当探测器报警后会自动切换到当前地图，探测器图标红色闪烁，探测器图标实时显示当前的浓度值。双击探测器按钮图标，会跳转到该探测器的详细信息界面，在该界面上后期可以按照实际用户需求定制回控操作。</span></p><h3 id='44-曲线监控'><span>4.4 曲线监控</span></h3><p><span>在本页面可以查看某个探测器的实时曲线，第一步先选择通信端口，第二步选择控制器，第三步选择探测器，然后就可以在左侧看到实时曲线，颜色可以在系统设置中设置。单击打印按钮会将当前曲线以截图的形式打印出来。勾选暂停显示记录数据复选框会暂停显示当前的数据。</span></p><h4 id='441-实时曲线'><span>4.4.1 实时曲线</span></h4><p><span> </span><img src="snap/4-4-1.jpg" referrerpolicy="no-referrer"></p><h4 id='442-历史曲线'><span>4.4.2 历史曲线</span></h4><p><span> </span><img src="snap/4-4-2.jpg" referrerpolicy="no-referrer"></p><h2 id='5-数据查询'><span>5 数据查询</span></h2><h3 id='51-报警记录'><span>5.1 报警记录</span></h3><p><span>在本页面，可以指定日期范围查询报警记录，还可以查询单个的控制器或者探测器的报警记录。也可以手动输入探测器的位号进行查询，下拉选择探测器后会自动填入位号。还可以选择报警类型（浓度上限报警、浓度下限报警）查询对应的类型，也可以输入报警值进行精准查询。</span></p><p><span>如果数据超过一页，会自动分页处理，单击右侧的上一页、下一页、第一页、末一页进行翻页查看，所有查询的数据可以导出到excel表格，也可以直接打印。单击删除按钮会弹出时间范围选择框，选择该时间段后确定，会删除该时间段的所有记录。</span></p><p><span>双击对应的报警记录可以打开警情确认对话框，重新填写确认意见，鼠标右键弹出删除记录菜单，可以删除当前选中的记录，支持多选，例如按住Ctrl键选择多个记录。</span></p><h4 id='511-记录查询'><span>5.1.1 记录查询</span></h4><p><span> </span><img src="snap/5-1-1.jpg" referrerpolicy="no-referrer"></p><h4 id='512-记录打印'><span>5.1.2 记录打印</span></h4><p><span> </span><img src="snap/5-1-2.jpg" referrerpolicy="no-referrer"></p><h4 id='513-记录导出'><span>5.1.3 记录导出</span></h4><p><span> </span><img src="snap/5-1-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/5-1-4.jpg" referrerpolicy="no-referrer"></p><h3 id='52-运行记录'><span>5.2 运行记录</span></h3><p><span>在本页面，可以指定日期范围查询运行记录，还可以查询单个的控制器或者探测器的运行记录。也可以手动输入探测器的位号进行查询，下拉选择探测器后会自动填入位号。</span></p><p><span>如果数据超过一页，会自动分页处理，单击右侧的上一页、下一页、第一页、末一页进行翻页查看，所有查询的数据可以导出到excel表格，也可以直接打印。单击删除按钮会弹出时间范围选择框，选择该时间段后确定，会删除该时间段的所有记录。</span></p><h4 id='521-记录查询'><span>5.2.1 记录查询</span></h4><p><span> </span><img src="snap/5-2-1.jpg" referrerpolicy="no-referrer"></p><h4 id='522-记录打印'><span>5.2.2 记录打印</span></h4><p><span> </span><img src="snap/5-2-2.jpg" referrerpolicy="no-referrer"></p><h4 id='523-记录导出'><span>5.2.3 记录导出</span></h4><p><span> </span><img src="snap/5-2-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/5-2-4.jpg" referrerpolicy="no-referrer"></p><h3 id='53-操作记录'><span>5.3 操作记录</span></h3><p><span>所有的用户操作都会记录到系统数据库，包括清空报警记录、删除记录、清空报警信息等操作。可以在本界面选择时间段范围查询，也可以选择日志类型（用户操作、设备上报）进行查询。 </span></p><p><span>如果数据超过一页，会自动分页处理，单击右侧的上一页、下一页、第一页、末一页进行翻页查看，所有查询的数据可以导出到excel表格，也可以直接打印。单击删除按钮会弹出时间范围选择框，选择该时间段后确定，会删除该时间段的所有记录。</span></p><h4 id='531-记录查询'><span>5.3.1 记录查询</span></h4><p><span> </span><img src="snap/5-3-1.jpg" referrerpolicy="no-referrer"></p><h4 id='532-记录打印'><span>5.3.2 记录打印</span></h4><p><span> </span><img src="snap/5-3-2.jpg" referrerpolicy="no-referrer"></p><h4 id='533-记录导出'><span>5.3.3 记录导出</span></h4><p><span> </span><img src="snap/5-3-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/5-3-4.jpg" referrerpolicy="no-referrer"></p><h2 id='6-通信协议'><span>6 通信协议</span></h2><h3 id='61-通信流程'><span>6.1 通信流程</span></h3><ol start='' ><li><span>整体的结构是：控制器挂在通信端口，一个控制器下有多个探测器节点，相当于主设备、子设备。</span></li><li><span>因为是需要遍历轮询，所以一个通信端口上的控制器地址不能重复。</span></li><li><span>不同通信端口，控制器地址可以重复，所以如果控制器数量较多可以分在不同的通信端口。</span></li><li><span>一个控制器可以挂多个探测器，控制器平时也在不断轮询探测器的数据并记录，等待上位机程序的轮询命令后，将探测器数据一起打包发回。</span></li><li><span>本软件只和控制器通信，不和探测器通信，控制器负责和探测器通信。为何这样设计？因为这种架构最通用，可接的设备数量也是最大的。</span></li><li><span>本系统默认按照标准modbus协议进行通信，modbus是标准的通信框架协议，支持串口和网络等通信方式，至于具体是通过串口还是网络通信根据设备厂家选择。</span></li><li><span>modbus是通信协议框架，至于具体数据位的每个字节对应的数据含义，每个厂家不一样，都是厂家自定义，一般2个字节表示一个数据。</span></li><li><span>端口可以是串口和网络，在添加端口时候可选择不同通信解析协议。</span></li></ol><h4 id='611-fc1003-1'><span>6.1.1 FC1003-1</span></h4><p><span> </span><img src="snap/6-1-1.jpg" referrerpolicy="no-referrer"></p><h4 id='612-fc1003-8'><span>6.1.2 FC1003-8</span></h4><p><span> </span><img src="snap/6-1-2.jpg" referrerpolicy="no-referrer"></p><h4 id='613-fc1003-16'><span>6.1.3 FC1003-16</span></h4><p><span> </span><img src="snap/6-1-3.jpg" referrerpolicy="no-referrer"></p><h4 id='614-fc1103显示板'><span>6.1.4 FC1103显示板</span></h4><p><span> </span><img src="snap/6-1-4.jpg" referrerpolicy="no-referrer"></p><h4 id='615-sams-4128'><span>6.1.5 SAMS-4128</span></h4><p><span> </span><img src="snap/6-1-5.jpg" referrerpolicy="no-referrer"></p><h4 id='616-ft21047p'><span>6.1.6 FT21047P</span></h4><p><span> </span><img src="snap/6-1-6.jpg" referrerpolicy="no-referrer"></p><h3 id='62-协议解释'><span>6.2 协议解释</span></h3><ol start='' ><li><span>主机发送是软件发送数据给设备，主动发送。</span></li><li><span>从机应答是设备根据收到的数据后作出应答数据，被动回复。</span></li><li><span>一条发送命令会对应一条应答命令。</span></li><li><span>寄存器地址2字节，高位在前低位在后。</span></li><li><span>读取长度2字节，高位在前低位在后。</span></li><li><span>数据位2字节，高位在前低位在后。</span></li><li><span>CRC校验2字节，低位在前高位在后。</span></li><li><span>功能码有 03（读只读寄存器）、04（读可读可写寄存器）、06（写读写寄存器）。</span></li><li><span>主机发送的功能码和从机应答的功能码相同。</span></li></ol><h4 id='621-主机发送'><span>6.2.1 主机发送</span></h4><figure><table><thead><tr><th style='text-align:left;' ><span>地址</span></th><th style='text-align:left;' ><span>功能码</span></th><th style='text-align:left;' ><span>寄存器地址</span></th><th style='text-align:left;' ><span>寄存器个数</span></th><th style='text-align:left;' ><span>CRC校验</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>01</span></td><td style='text-align:left;' ><span>03</span></td><td style='text-align:left;' ><span>00 00</span></td><td style='text-align:left;' ><span>00 04</span></td><td style='text-align:left;' ><span>44 09</span></td></tr></tbody></table></figure><h4 id='622-从机应答'><span>6.2.2 从机应答</span></h4><figure><table><thead><tr><th style='text-align:left;' ><span>地址</span></th><th style='text-align:left;' ><span>功能码</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>数据位1</span></th><th style='text-align:left;' ><span>数据位2</span></th><th style='text-align:left;' ><span>数据位3</span></th><th style='text-align:left;' ><span>数据位4</span></th><th style='text-align:left;' ><span>CRC校验</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>01</span></td><td style='text-align:left;' ><span>03</span></td><td style='text-align:left;' ><span>08</span></td><td style='text-align:left;' ><span>00 00</span></td><td style='text-align:left;' ><span>00 00</span></td><td style='text-align:left;' ><span>00 00</span></td><td style='text-align:left;' ><span>00 00</span></td><td style='text-align:left;' ><span>95 D7</span></td></tr></tbody></table></figure><h4 id='623-读取长度'><span>6.2.3 读取长度</span></h4><figure><table><thead><tr><th style='text-align:left;' ><span>设备型号</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>FC1003-1</span></td><td style='text-align:left;' ><span>01</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>FC1003-8</span></td><td style='text-align:left;' ><span>08</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>FC1003-16</span></td><td style='text-align:left;' ><span>08 08</span></td><td style='text-align:left;' ><span>相当与两台FC1003-8，设备地址不同。</span></td></tr><tr><td style='text-align:left;' ><span>FC1003显示板</span></td><td style='text-align:left;' ><span>40</span></td><td style='text-align:left;' ><span>长度根据所接设备数量不同需要调整，最大为64个。</span></td></tr><tr><td style='text-align:left;' ><span>FC1003底板</span></td><td style='text-align:left;' ><span>04</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>FT2104P</span></td><td style='text-align:left;' ><span>01</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>SAMS-4128</span></td><td style='text-align:left;' ><span>08</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h4 id='624-数据举例'><span>6.2.4 数据举例</span></h4><p><strong><span>提示说明</span></strong></p><ol start='' ><li><span>以下举例数据CRC校验位统一用 XX XX 表示，懒得计算。</span></li><li><span>本系统中填写的地址都是从1开始计数，所以填1则表示从0开始读取。</span></li><li><span>如果寄存器地址 01 01 ，则0101=257，本系统中要填258，填258实际是-1=257=0101发送。</span></li><li><span>寄存器个数，也可以说是节点设备的数量。</span></li><li><span>一个数据位或者说一个节点的数据是2个字节数据。</span></li><li><span>读取长度1则会返回1个数据位共2字节数据。</span></li><li><span>读取长度2则会返回2个数据位共4字节数据。</span></li><li><span>读取长度3则会返回3个数据位共6字节数据。</span></li></ol><p><strong><span>示例数据1</span></strong></p><ul><li><span>发送：01 03 00 00 00 02 XX XX</span></li><li><span>解释：从寄存器地址0（00 00 = 0）开始，读取2个寄存器。</span></li><li><span>返回：01 03 04 42 C7 FF EA XX XX</span></li><li><span>解释：返回4字节数据 42 C7 FF EA ，对应寄存器地址 0、1 的数据。</span></li><li><span>配置：控制器地址1，探测器地址1、2。</span></li></ul><p><strong><span>示例数据2</span></strong></p><ul><li><span>发送：01 03 01 01 00 01 XX XX</span></li><li><span>解释：从寄存器地址257（01 01 = 257）开始，读取1个寄存器。</span></li><li><span>返回：01 03 02 02 EF XX XX</span></li><li><span>解释：返回2字节数据 02 EF ，对应寄存器地址257的数据。</span></li><li><span>配置：控制器地址1，探测器地址258。</span></li></ul><p><strong><span>示例数据3</span></strong></p><ul><li><span>发送：AA 03 AA BB 00 04 XX XX</span></li><li><span>解释：从寄存器地址43707（AA BB = 43707）开始，读取4个寄存器。</span></li><li><span>返回：AA 03 08 55 AC 23 65 84 77 C3 3F XX XX</span></li><li><span>解释：返回8字节数据 55 AC 23 65 84 77 C3 3F ，对应寄存器地址43707、43708、43709、43710的数据。</span></li><li><span>配置：控制器地址170（AA = 170），探测器地址43708、43709、43710、43711。</span></li></ul><h4 id='625-继电器联动'><span>6.2.5 继电器联动</span></h4><figure><table><thead><tr><th style='text-align:left;' ><span>发送</span></th><th style='text-align:left;' ><span>返回</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>01 03 00 00 00 01 84 0A</span></td><td style='text-align:left;' ><span>01 03 02 00 00 B8 44</span></td><td style='text-align:left;' ><span>读取设备状态</span></td></tr><tr><td style='text-align:left;' ><span>01 06 00 00 00 01 48 0A</span></td><td style='text-align:left;' ><span>01 06 00 00 00 01 48 0A</span></td><td style='text-align:left;' ><span>打开继电器1</span></td></tr><tr><td style='text-align:left;' ><span>01 06 00 00 00 03 C9 CB</span></td><td style='text-align:left;' ><span>01 06 00 00 00 03 C9 CB</span></td><td style='text-align:left;' ><span>打开继电器1、2</span></td></tr><tr><td style='text-align:left;' ><span>01 06 00 00 00 07 C8 08</span></td><td style='text-align:left;' ><span>01 06 00 00 00 07 C8 08</span></td><td style='text-align:left;' ><span>打开继电器1、2、3</span></td></tr><tr><td style='text-align:left;' ><span>01 06 00 00 00 06 09 C8</span></td><td style='text-align:left;' ><span>01 06 00 00 00 06 09 C8</span></td><td style='text-align:left;' ><span>关闭继电器1</span></td></tr><tr><td style='text-align:left;' ><span>01 06 00 00 00 04 88 09</span></td><td style='text-align:left;' ><span>01 06 00 00 00 04 88 09</span></td><td style='text-align:left;' ><span>关闭继电器1、2</span></td></tr><tr><td style='text-align:left;' ><span>01 06 00 00 00 00 89 CA</span></td><td style='text-align:left;' ><span>01 06 00 00 00 00 89 CA</span></td><td style='text-align:left;' ><span>关闭继电器1、2、3</span></td></tr></tbody></table></figure><h2 id='7-各系统运行图'><span>7 各系统运行图</span></h2><h3 id='70-样式风格'><span>7.0 样式风格</span></h3><p><span> </span><img src="snap/7-0-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/7-0-3.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/7-0-5.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/7-0-11.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/7-0-15.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/7-0-17.jpg" referrerpolicy="no-referrer"></p><h3 id='71-windows-mingw'><span>7.1 windows-mingw</span></h3><p><span> </span><img src="snap/7-1-1.jpg" referrerpolicy="no-referrer"></p><h3 id='72-windows-msvc'><span>7.2 windows-msvc</span></h3><p><span> </span><img src="snap/7-2-1.jpg" referrerpolicy="no-referrer"></p><h3 id='73-linux-ubuntu'><span>7.3 linux-ubuntu</span></h3><p><span> </span><img src="snap/7-3-1.jpg" referrerpolicy="no-referrer"></p><h3 id='74-linux-uos'><span>7.4 linux-uos</span></h3><p><span> </span><img src="snap/7-4-1.jpg" referrerpolicy="no-referrer"></p><h3 id='75-linux-kylin'><span>7.5 linux-kylin</span></h3><p><span> </span><img src="snap/7-5-1.jpg" referrerpolicy="no-referrer"></p><h3 id='76-linux-neokylin'><span>7.6 linux-neokylin</span></h3><p><span> </span><img src="snap/7-6-1.jpg" referrerpolicy="no-referrer"></p><h3 id='77-linux-centos'><span>7.7 linux-centos</span></h3><p><span> </span><img src="snap/7-7-1.jpg" referrerpolicy="no-referrer"></p><h3 id='78-linux-fedora'><span>7.8 linux-fedora</span></h3><p><span> </span><img src="snap/7-8-1.jpg" referrerpolicy="no-referrer"></p><h3 id='79-unix-mac'><span>7.9 unix-mac</span></h3><p><span> </span><img src="snap/7-9-1.jpg" referrerpolicy="no-referrer"></p><h2 id='8-程序框架说明'><span>8 程序框架说明</span></h2><ul><li><span>下面的截图和说明未必是最新的，但是大部分是一致的。</span></li><li><span>整体的框架不会改变，可能会有新增加子模块和代码，具体以最新的代码为准。</span></li><li><span>程序会一直更新完善，不断迭代中。</span></li></ul><h3 id='81-整体代码结构'><span>8.1 整体代码结构</span></h3><p><span> </span><img src="snap/8-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统采用模块化的设备，有用到第三方开源类库比如串口通信qextserialport，全部放在3rd下面，有用到很多自己封装完善的通用类库比如数据导入导出组件，全部放在core下面，设备通信和辅助处理全部放在class下面，所有界面全部放在ui下面，相当于一个个小的组件合起来，最终形成了整个监控系统的完整代码。</span></p><h3 id='82-主模块说明'><span>8.2 主模块说明</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>3rd</span></td><td style='text-align:left;' ><span>一些第三方开源的类库，比如串口通信qextserialport。</span></td></tr><tr><td style='text-align:left;' ><span>class</span></td><td style='text-align:left;' ><span>存放系统初始化、样式控制、自定义控件、设备通信等。</span></td></tr><tr><td style='text-align:left;' ><span>core</span></td><td style='text-align:left;' ><span>本人一直持续更新完善的通用的类库，比如数据导入导出组件。</span></td></tr><tr><td style='text-align:left;' ><span>ui</span></td><td style='text-align:left;' ><span>所有的界面都分门别类放在这里。</span></td></tr></tbody></table></figure><h3 id='83-子模块说明'><span>8.3 子模块说明</span></h3><h4 id='831-第三方类库'><span>8.3.1 第三方类库</span></h4><p><span> </span><img src="snap/8-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>这里放的全部是第三方开源的轮子，感谢开源、感谢github、gitee等开源社区。具体代码不做过多说明，网上会有很多介绍和使用说明。</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>3rd_qcustomplot</span></td><td style='text-align:left;' ><span>第三方精美图表控件qcustomplot，Qt自带的qchart功能有限而且不支持大量数据。</span></td></tr><tr><td style='text-align:left;' ><span>3rd_qextserialport</span></td><td style='text-align:left;' ><span>第三方串口通信qextserialport，这个类比较稳定可靠，经过了几十个项目持续数十年运行的考验，不用Qt自带的串口类。</span></td></tr><tr><td style='text-align:left;' ><span>3rd_qtpropertybrowser</span></td><td style='text-align:left;' ><span>第三方属性控件，指定控件自动读取对应的属性形成属性栏。</span></td></tr><tr><td style='text-align:left;' ><span>3rd_smtpclient</span></td><td style='text-align:left;' ><span>第三方发送邮件组件，走底层socket协议发送邮件。</span></td></tr></tbody></table></figure><h4 id='832-通信及辅助类'><span>8.3.2 通信及辅助类</span></h4><p><span> </span><img src="snap/8-3-2.jpg" referrerpolicy="no-referrer"></p><p><span>这里放的都是一些系统初始化、设备通信相关的类。</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>api</span></td><td style='text-align:left;' ><span>存放数据库表映射成对应的全局队列数据、数据库查询类，告警短信转发及告警邮件转发类。</span></td></tr><tr><td style='text-align:left;' ><span>app</span></td><td style='text-align:left;' ><span>全局配置参数管理类、全局变量类、全局事件转发器，通用函数等。</span></td></tr><tr><td style='text-align:left;' ><span>device</span></td><td style='text-align:left;' ><span>设备通信管理，比如设备采集处理、数据库采集、报警联动等。</span></td></tr><tr><td style='text-align:left;' ><span>usercontrol</span></td><td style='text-align:left;' ><span>当前系统的用到的自定义控件全部放在这里，项目通用的自定义控件放在core_control中。</span></td></tr></tbody></table></figure><h5 id='8321-模块-api'><span>8.3.2.1 模块-api</span></h5><p><span> </span><img src="snap/8-3-2-1.jpg" referrerpolicy="no-referrer"><span>	</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>dbdata</span></td><td style='text-align:left;' ><span>将数据库表映射到全局变量数据队列，比如将端口信息表portinfo转成QStringList存放一行行数据，这样在程序中运算比较速度极快，直接内存比较，不用每次都去读取数据库。</span></td></tr><tr><td style='text-align:left;' ><span>dbquery</span></td><td style='text-align:left;' ><span>所有的数据库查询插入更新等操作都在这里，比如查询探测器信息表、控制器信息表、插入日志记录等。</span></td></tr><tr><td style='text-align:left;' ><span>sendserver</span></td><td style='text-align:left;' ><span>通用的发送短信和邮件管理类，因为发送的内容是一致的所有统一一个类来管理，调用同一个函数就行。</span></td></tr></tbody></table></figure><h5 id='8322-模块-app'><span>8.3.2.2 模块-app</span></h5><p><span> </span><img src="snap/8-3-2-2.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>appconfig</span></td><td style='text-align:left;' ><span>配置参数类，整个系统的配置参数存放在ini文件中，跨平台，所有参数都对应一个变量，读取配置参数的时候将值赋值给变量，写入的时候将变量值写入到配置文件。</span></td></tr><tr><td style='text-align:left;' ><span>appdata</span></td><td style='text-align:left;' ><span>全局变量类，系统中无可避免需要一些全局变量方便处理，都放在此类，比如版本号、当前用户信息、地图宽度高度、左侧右侧顶部底部宽高等。</span></td></tr><tr><td style='text-align:left;' ><span>appevent</span></td><td style='text-align:left;' ><span>全局事件转发类，系统越复杂信号需要传递的层级越多，所以需要一个全局事件转发类，用来中转这些事件，这样永远只需要两层就可以收到信号进行处理，而且整个系统看起来干净整洁，不会说一个信号传递到了N个地方乱七八糟，建议需要跨层级传递的信号都放在这里中转。比如软件退出信号，可能多个界面需要收到退出信号进行保存和其他处理，如果从关闭界面发出信号传递给需要的界面，那不知道要中间层层传递多少次，有了这个全局事件转发类，你只需要将事件传给appevent，需要接收事件的地方关联这个信号就行，appevent为全局单例类，整个系统唯一。 通用的一些信号有软件退出、全局样式改变、主窗体变化（0-最小化 1-最大化 2-恢复 3-关闭 4-移动 5-尺寸变化）等。</span></td></tr><tr><td style='text-align:left;' ><span>appinit</span></td><td style='text-align:left;' ><span>程序初始化类，在main函数中，会先执行这个初始化的类，比如初始化皮肤、字体、数据库、样式等操作，这些都是要优先在窗体加载前执行的，执行完毕以后再打开窗体主界面。</span></td></tr><tr><td style='text-align:left;' ><span>appstyle</span></td><td style='text-align:left;' ><span>全局样式管理类，整个系统的样式全部放在这里，一般加载流程是先读取样式表文件，然后将本系统独特的样式（比如开关按钮、视频监控、云台仪表盘）内容追加到后面，最后统一设置全局样式，在main函数中加载，和appinit类一样放在最前面执行。</span></td></tr></tbody></table></figure><h5 id='8323-模块-device'><span>8.3.2.3 模块-device</span></h5><p><span> </span><img src="snap/8-3-2-3.jpg" referrerpolicy="no-referrer"><span>	</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>alarmlink</span></td><td style='text-align:left;' ><span>报警联动处理类，探测器报警后，根据联动设置中设置的规则，将发送联动指令到总线上的设备。</span></td></tr><tr><td style='text-align:left;' ><span>dbreceive</span></td><td style='text-align:left;' ><span>数据库采集类，通过数据库采集的方式来读取设备的状态和值，系统默认是设备采集，通过485总线modbus协议等去轮询设备的状态，为了拓展兼容性，还有一种场景是用户自己有自己的采集和算法，然后将结果存储到了数据库表中，需要用UI界面将数据库中的值展现出来。</span></td></tr><tr><td style='text-align:left;' ><span>deviceclient</span></td><td style='text-align:left;' ><span>设备采集类，本系统的核心，所有的通信解析都在此类中，因为数据内容格式一致，所以串口和网络通信收发都放在一起，这样解析起来完全一致。</span></td></tr><tr><td style='text-align:left;' ><span>devicedata</span></td><td style='text-align:left;' ><span>获取采集发送指令类，为了应对不同的场景，针对不同的工作模式，会有发送不同的采集指令。</span></td></tr><tr><td style='text-align:left;' ><span>devicehelper</span></td><td style='text-align:left;' ><span>整个系统设备管理辅助类，比如插入窗口消息、加载设备列表、加载图片地图、加载设备按钮等。</span></td></tr><tr><td style='text-align:left;' ><span>devicemap</span></td><td style='text-align:left;' ><span>设备图片地图管理类，相当于一次性加载所有图片到内存，当要切换或者显示的时候，直接从内存取出来设置即可，速度极快，瞬间相应，纯粹是为了加快相应速度以及可能在图片上进行绘制增加的功能，比从文件系统读取图片文件显示快N倍。</span></td></tr><tr><td style='text-align:left;' ><span>deviceserver</span></td><td style='text-align:left;' ><span>设备通信服务类，对应上面的deviceclient类，这里面负责从数据库查询有多少个端口和设备，实例化对应的client，关联信号进行统一的处理，同时还包括定时器处理记录的存储，定时器处理报警等。</span></td></tr><tr><td style='text-align:left;' ><span>udpreceive</span></td><td style='text-align:left;' ><span>数据转发UDP接收端，接收到转发的数据以后解析并反映到界面上。</span></td></tr><tr><td style='text-align:left;' ><span>udpsend</span></td><td style='text-align:left;' ><span>数据转发UDP发送端，负责将采集到的数据转发出去。</span></td></tr></tbody></table></figure><h5 id='8324-模块-usercontrol'><span>8.3.2.4 模块-usercontrol</span></h5><p><span> </span><img src="snap/8-3-2-4.jpg" referrerpolicy="no-referrer"><span>	</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>gaugecar</span></td><td style='text-align:left;' ><span>汽车仪表盘，用来指示气体的值。</span></td></tr><tr><td style='text-align:left;' ><span>gaugespeed</span></td><td style='text-align:left;' ><span>速度仪表盘，用来指示气体的值。</span></td></tr><tr><td style='text-align:left;' ><span>selectwidget</span></td><td style='text-align:left;' ><span>描点跟随窗体控件，用在属性设计过程中拖曳控件，然后拉伸拖动。</span></td></tr></tbody></table></figure><h4 id='833-核心通用类库'><span>8.3.3 核心通用类库</span></h4><p><span> </span><img src="snap/8-3-3.jpg" referrerpolicy="no-referrer"></p><p><span>这里放的全部是个人一直持续更新完善的独创的轮子，所有的项目都公用这些轮子，用到哪个就包含哪个进来，更新只需要更新轮子代码就行。</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>core_common</span></td><td style='text-align:left;' ><span>通用函数，包括通用秘钥、通用导航、通用样式、声音播放、日志记录、运行时间记录等。</span></td></tr><tr><td style='text-align:left;' ><span>core_control</span></td><td style='text-align:left;' ><span>通用自定义控件，很多系统经常用到的控件全部放在这里，比如开关按钮、设备容器、设备按钮、颜色下拉框等。</span></td></tr><tr><td style='text-align:left;' ><span>core_customplot</span></td><td style='text-align:left;' ><span>继承自qcustomplot类的自定义图表组件，同时兼容各种qcustomplot版本，这样就可以在任意的Qt版本使用图表控件。</span></td></tr><tr><td style='text-align:left;' ><span>core_dataout</span></td><td style='text-align:left;' ><span>数据导入导出到xls/pdf和打印类库，极速、跨平台、无依赖。</span></td></tr><tr><td style='text-align:left;' ><span>core_db</span></td><td style='text-align:left;' ><span>数据库通用类库比如数据库线程管理、数据清理、数据采集等。</span></td></tr><tr><td style='text-align:left;' ><span>core_form</span></td><td style='text-align:left;' ><span>通用的窗体相关的组件，包括用户登录、用户退出、用户管理、权限管理、数据库管理，同时还包括封装的项目上直接用的导入导出、打印等。</span></td></tr><tr><td style='text-align:left;' ><span>core_qui</span></td><td style='text-align:left;' ><span>通用的辅助类，包括自定义对话框，全局辅助函数，图形字体等。</span></td></tr><tr><td style='text-align:left;' ><span>core_send</span></td><td style='text-align:left;' ><span>多线程短信发送和邮件发送类，功能类似所有放在一起。</span></td></tr></tbody></table></figure><h5 id='8331-模块-corecommon'><span>8.3.3.1 模块-core_common</span></h5><p><span> </span><img src="snap/8-3-3-1.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>base64helper</span></td><td style='text-align:left;' ><span>图片及文字和base64编码之间转换的类。</span></td></tr><tr><td style='text-align:left;' ><span>commonkey</span></td><td style='text-align:left;' ><span>通用秘钥管理类，指定校验秘钥文件，可设置运行时间、设备数量等限制，支持根据硬件指纹特征生成机器码文件等。</span></td></tr><tr><td style='text-align:left;' ><span>commonnav</span></td><td style='text-align:left;' ><span>通用菜单导航管理类，用来控制和显示顶部导航栏、左侧导航栏的样式。很多子界面需要用到，所以封装成一个专门管理这个的类。</span></td></tr><tr><td style='text-align:left;' ><span>commonstyle</span></td><td style='text-align:left;' ><span>通用样式管理类，比如Qt自带类窗体样式、自定义控件样式、分页导航样式、导航按钮样式、开关按钮样式等。相当于将多个项目常用的自定义样式封装一起做成通用。</span></td></tr><tr><td style='text-align:left;' ><span>framelesswidget2</span></td><td style='text-align:left;' ><span>无边框窗体拉伸类，边框四周八个方位都可以自由拉伸，可设置是否允许拖动和拉伸。</span></td></tr><tr><td style='text-align:left;' ><span>playwav</span></td><td style='text-align:left;' ><span>声音文件播放类，通用Qt456，自动识别当前Qt版本使用对应的类，Qt4采用QSound，Qt5以上采用QSoundEffect，嵌入式采用对应的命令行aplay、mpv来播放。</span></td></tr><tr><td style='text-align:left;' ><span>savelog</span></td><td style='text-align:left;' ><span>日志钩子类，将系统中所有的打印信息转为日志存储或者输出到网络等，可以开启用来打印输出日志信息。</span></td></tr><tr><td style='text-align:left;' ><span>saveruntime</span></td><td style='text-align:left;' ><span>保存运行时间类，用来存储系统启动后每隔一段时间就输出一条记录用来记录启动后软件运行了多久，方便分析问题。</span></td></tr></tbody></table></figure><h5 id='8332-模块-corecontrol'><span>8.3.3.2 模块-core_control</span></h5><p><span> </span><img src="snap/8-3-3-2.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>bottomwidget</span></td><td style='text-align:left;' ><span>通用底部状态栏控件，可以设置软件名称、版本号、运行时间等。</span></td></tr><tr><td style='text-align:left;' ><span>colorcombobox</span></td><td style='text-align:left;' ><span>颜色下拉框控件，在系统设置中有。</span></td></tr><tr><td style='text-align:left;' ><span>cpumemorylabel</span></td><td style='text-align:left;' ><span>CPU和内存使用情况标签控件，主界面右上角显示。</span></td></tr><tr><td style='text-align:left;' ><span>customtitlebar</span></td><td style='text-align:left;' ><span>停靠窗体自定义标题栏控件。</span></td></tr><tr><td style='text-align:left;' ><span>devicebutton</span></td><td style='text-align:left;' ><span>设备按钮控件，比如图片地图模块中用到，可设置不同的图标样式和状态等，双击发出信号进行相应处理比如弹出对应窗体等。</span></td></tr><tr><td style='text-align:left;' ><span>lcddatetime</span></td><td style='text-align:left;' ><span>软件右上角显示时间的控件。</span></td></tr><tr><td style='text-align:left;' ><span>panelwidget</span></td><td style='text-align:left;' ><span>面板容器控件，主界面子模块表格消息，就用到此控件，用于将一堆widget放到此容器进行管理，自动形成滚动条等。</span></td></tr><tr><td style='text-align:left;' ><span>switchbutton</span></td><td style='text-align:left;' ><span>开关按钮控件，在系统设置中存在大量该控件。</span></td></tr><tr><td style='text-align:left;' ><span>xslider</span></td><td style='text-align:left;' ><span>滑动条控件，在原有滑动条基础上增加了鼠标按下立即定位等。</span></td></tr></tbody></table></figure><h5 id='8333-模块-corecustomplot'><span>8.3.3.3 模块-core_customplot</span></h5><p><span> </span><img src="snap/8-3-3-3.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>customplot</span></td><td style='text-align:left;' ><span>自定义图表控件主类，使用的时候只要new这个类就行。</span></td></tr><tr><td style='text-align:left;' ><span>customplotbarh</span></td><td style='text-align:left;' ><span>自定义形状-横向柱状图。</span></td></tr><tr><td style='text-align:left;' ><span>customplotbarv</span></td><td style='text-align:left;' ><span>自定义形状-垂直柱状图。</span></td></tr><tr><td style='text-align:left;' ><span>customplothead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>customplothelper</span></td><td style='text-align:left;' ><span>当前组件通用辅助函数文件。</span></td></tr><tr><td style='text-align:left;' ><span>customplotline</span></td><td style='text-align:left;' ><span>自定义形状-平滑曲线图。</span></td></tr><tr><td style='text-align:left;' ><span>customplottracer</span></td><td style='text-align:left;' ><span>自定义图层绘制十字线，也叫游标，定位线。</span></td></tr><tr><td style='text-align:left;' ><span>smoothcurve</span></td><td style='text-align:left;' ><span>平滑曲线算法类，内置多种平滑算法，可以自行增加其他算法。</span></td></tr></tbody></table></figure><h5 id='8334-模块-coredataout'><span>8.3.3.4 模块-core_dataout</span></h5><p><span> </span><img src="snap/8-3-3-4.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>datacreat</span></td><td style='text-align:left;' ><span>通用数据报表内容创建类，比如生成表格格式的html内容，然后赋值给dataprint直接打印，里面举例了图文混排的报告内容，后期会不断增加其他模板，也可以自行增加其他模板数据。</span></td></tr><tr><td style='text-align:left;' ><span>datacsv</span></td><td style='text-align:left;' ><span>导入导出数据，csv格式，可设置分隔符。拓展名。过滤条件等。</span></td></tr><tr><td style='text-align:left;' ><span>datahead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>datahelper</span></td><td style='text-align:left;' ><span>辅助类，比如校验规则函数，通用数据导出+打印函数。</span></td></tr><tr><td style='text-align:left;' ><span>dataprint</span></td><td style='text-align:left;' ><span>数据打印到pdf及纸张，支持多线程。</span></td></tr><tr><td style='text-align:left;' ><span>dataxls</span></td><td style='text-align:left;' ><span>数据导出到xls类，支持多线程导出。</span></td></tr></tbody></table></figure><h5 id='8335-模块-coredb'><span>8.3.3.5 模块-core_db</span></h5><p><span> </span><img src="snap/8-3-3-5.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>dbcleanthread</span></td><td style='text-align:left;' ><span>自动清理数据线程类。</span></td></tr><tr><td style='text-align:left;' ><span>dbconnthread</span></td><td style='text-align:left;' ><span>数据库通信管理线程类。</span></td></tr><tr><td style='text-align:left;' ><span>dbdelegate</span></td><td style='text-align:left;' ><span>自定义委托全家桶，包括复选框、下拉框、密码框、按钮等。</span></td></tr><tr><td style='text-align:left;' ><span>dbhead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>dbhelper</span></td><td style='text-align:left;' ><span>各种数据库应用函数封装，比如初始化数据库、执行sql语句等。</span></td></tr><tr><td style='text-align:left;' ><span>dbhttpthread</span></td><td style='text-align:left;' ><span>网络请求数据采集类。</span></td></tr><tr><td style='text-align:left;' ><span>dbpage</span></td><td style='text-align:left;' ><span>数据库通用翻页类。</span></td></tr><tr><td style='text-align:left;' ><span>dbpagemodel</span></td><td style='text-align:left;' ><span>数据库翻页类数据模型。</span></td></tr><tr><td style='text-align:left;' ><span>navpage</span></td><td style='text-align:left;' ><span>分页导航控件。</span></td></tr></tbody></table></figure><h5 id='8336-模块-coreform'><span>8.3.3.6 模块-core_form</span></h5><p><span> </span><img src="snap/8-3-3-6.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>formhelper</span></td><td style='text-align:left;' ><span>封装的导入导出、导出数据到xls/pdf和打印数据、自动备份数据、保存最后打开的文件夹等。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigdb</span></td><td style='text-align:left;' ><span>通用数据库管理界面类，可选不同的数据库类型，填入用户信息，执行检测连接和初始化数据操作。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfiguser</span></td><td style='text-align:left;' ><span>通用用户管理界面类，可添加、删除、修改用户信息，包括权限分配等，可导入导出打印用户信息。</span></td></tr><tr><td style='text-align:left;' ><span>frmlogin</span></td><td style='text-align:left;' ><span>通用用户登录界面类，包括自动登录和记住密码复选框，多次密码错误校验，记住当前用户信息等。三次错误关闭，下拉可选用户，内置超级密码。</span></td></tr><tr><td style='text-align:left;' ><span>frmlogout</span></td><td style='text-align:left;' ><span>通用用户退出界面类，三次错误关闭，下拉可选用户，内置超级密码。</span></td></tr><tr><td style='text-align:left;' ><span>userhelper</span></td><td style='text-align:left;' ><span>通用用户权限管理类，内置7种类型权限，对应权限名称可自定义，一般在用户切换对应界面或者单击了对应功能按钮的时候触发。</span></td></tr></tbody></table></figure><h5 id='8337-模块-corequi'><span>8.3.3.7 模块-core_qui</span></h5><p><span> </span><img src="snap/8-3-3-7.jpg" referrerpolicy="no-referrer"></p><p><span>本组件涵盖的功能较多，所以采用了分层管理代码结构。</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>iconhelper</span></td><td style='text-align:left;' ><span>万能图形字体类，可传入多种图形字体文件，一个类通用所有图形字体。</span></td></tr><tr><td style='text-align:left;' ><span>quiconfig</span></td><td style='text-align:left;' ><span>存储当前组件的配置参数信息，比如全局的字体名称、字号、无边框窗体的最小化最大化关闭等图标、样式表的颜色值。</span></td></tr><tr><td style='text-align:left;' ><span>quihead</span></td><td style='text-align:left;' ><span>当前组件通用头文件。</span></td></tr><tr><td style='text-align:left;' ><span>quistyle</span></td><td style='text-align:left;' ><span>当前组件通用样式设置管理类，可以指定枚举类型样式、传入样式内容设置、获取样式表文件对应的颜色值等。当前组件样式相关的处理函数都放在这里，统一管理。</span></td></tr></tbody></table></figure><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>quiabout</span></td><td style='text-align:left;' ><span>关于系统对话框，可传入软件标题、版本、版权、网址等信息。</span></td></tr><tr><td style='text-align:left;' ><span>quidateselect</span></td><td style='text-align:left;' ><span>自定义日期范围选择对话框。</span></td></tr><tr><td style='text-align:left;' ><span>quiinputbox</span></td><td style='text-align:left;' ><span>自定义输入框窗体，可指定不同的输入类型比如文本框、下拉框等。</span></td></tr><tr><td style='text-align:left;' ><span>quimessagebox</span></td><td style='text-align:left;' ><span>自定义信息消息框窗体，可设置关闭倒计时，不同的类型比如信息框、询问框、错误框等。</span></td></tr><tr><td style='text-align:left;' ><span>quisplash</span></td><td style='text-align:left;' ><span>自定义弹出提示信息，提示完自动消息关闭。</span></td></tr><tr><td style='text-align:left;' ><span>quitipbox</span></td><td style='text-align:left;' ><span>自定义右下角信息对话框，可设置对齐方式、关闭倒计时等。</span></td></tr><tr><td style='text-align:left;' ><span>quiwidget</span></td><td style='text-align:left;' ><span>自定义无边框窗体，可设置标题，各种图标等。</span></td></tr></tbody></table></figure><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>quihelper</span></td><td style='text-align:left;' ><span>项目通用辅助类，各种常用函数的封装，比如获取当前屏幕分辨率、设置字体、设置编码、加载翻译文件、各种进制数据转换、弹出各种对话框、设置延时时间等。</span></td></tr><tr><td style='text-align:left;' ><span>quihelpercore</span></td><td style='text-align:left;' ><span>获取当前桌面分辨率，设置编码、字体、翻译文件等。</span></td></tr><tr><td style='text-align:left;' ><span>quihelperdata</span></td><td style='text-align:left;' ><span>16进制、2进制、10进制互相转换，16进制字符串、字节数组互相转换，字节数组转int和short，CRC校验等。</span></td></tr><tr><td style='text-align:left;' ><span>quihelperfile</span></td><td style='text-align:left;' ><span>选择文件、保存文件、选择目录等对话框，复制文件、删除文件等。</span></td></tr><tr><td style='text-align:left;' ><span>quihelperform</span></td><td style='text-align:left;' ><span>设置无边框窗体、边框阴影，弹出信息框、错误框、询问框、日期选择框、关于对话框、中间提示框等。</span></td></tr><tr><td style='text-align:left;' ><span>quihelperimage</span></td><td style='text-align:left;' ><span>获取等比例缩放图片，通用设置logo图片，支持资源文件、本地图片、图形字体、svg自动变色等多种形式。</span></td></tr><tr><td style='text-align:left;' ><span>quihelpernet</span></td><td style='text-align:left;' ><span>获取本机IP地址集合，获取外网IP地址，判断IP、MAC等是否合法，下载网络文件，IP地址字符串与整型互相转换。</span></td></tr><tr><td style='text-align:left;' ><span>quihelperother</span></td><td style='text-align:left;' ><span>初始化数据库文件，设置系统时间、开机启动，设置图标到按钮，写入临时消息的文本文件等。</span></td></tr></tbody></table></figure><h5 id='8338-模块-coresend'><span>8.3.3.8 模块-core_send</span></h5><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>sendemailthread</span></td><td style='text-align:left;' ><span>多线程发送邮件类，支持附件，可设置多个抄送。</span></td></tr><tr><td style='text-align:left;' ><span>sendmsgthread</span></td><td style='text-align:left;' ><span>多线程收发短信类，支持长短信发送和多个收件人。</span></td></tr></tbody></table></figure><h4 id='834-界面ui'><span>8.3.4 界面UI</span></h4><p><span> </span><img src="snap/8-3-4.jpg" referrerpolicy="no-referrer"></p><p><strong><span>界面说明</span></strong></p><ul><li><span>这里分门别类存放的各种功能集合的界面类。</span></li><li><span>每个类都一个ui文件、一个h头文件、一个cpp实现文件。</span></li><li><span>可以方便快速查找对应功能的界面，也方便拓展增加界面。</span></li><li><span>不仅分文件夹存放的，而且命名也尽量按照对应功能打头，比如系统设置模块中的都用frmconfig打头。</span></li><li><span>外层文件夹是整齐的，内部代码也是整齐的。</span><span>	</span></li></ul><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmconfig</span></td><td style='text-align:left;' ><span>系统设置模块，包括基本设置、端口管理、控制器管理、探测器管理、联动设置、类型管理等。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfig2</span></td><td style='text-align:left;' ><span>其他设置模块，包括地图管理、用户管理、组态设计、设备调试等。</span></td></tr><tr><td style='text-align:left;' ><span>frmdata</span></td><td style='text-align:left;' ><span>日志查询模块，包括用户日志、运行日志、报警日志等。</span></td></tr><tr><td style='text-align:left;' ><span>frmmain</span></td><td style='text-align:left;' ><span>主界面模块，包括软件主界面、模拟调试工具等。</span></td></tr><tr><td style='text-align:left;' ><span>frmother</span></td><td style='text-align:left;' ><span>其他模块，包括封装的设备信息面板，设备回控等。</span></td></tr><tr><td style='text-align:left;' ><span>frmview</span></td><td style='text-align:left;' ><span>视图模块，包括数据监控、设备面板、地图监控、曲线监控等。</span></td></tr></tbody></table></figure><h5 id='8341-模块-frmconfig'><span>8.3.4.1 模块-frmconfig</span></h5><p><span> </span><img src="snap/8-3-4-1.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmconfig</span></td><td style='text-align:left;' ><span>系统设置模块主界面，采用堆栈窗体形式，加载多个子界面比如控制器管理、探测器管理等。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigdbnet</span></td><td style='text-align:left;' ><span>远程数据库设置，用于将本地数据实时同步到远程服务器。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigdevice</span></td><td style='text-align:left;' ><span>控制器管理，可以增加、删除、修改、清空、导入、导出、打印控制器信息。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfiglink</span></td><td style='text-align:left;' ><span>联动管理，可以增加、删除、修改、清空、导入、导出、打印联动信息。具体联动规则依据厂家约定。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfignode</span></td><td style='text-align:left;' ><span>探测器管理，可以增加、删除、修改、清空、导入、导出、打印探测器信息。本系统设备的最终节点，可以设置非常详细的各种参数。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigport</span></td><td style='text-align:left;' ><span>端口管理，可以增加、删除、修改、清空、导入、导出、打印端口信息。可以下拉选择对应的通信协议模式。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigsystem</span></td><td style='text-align:left;' ><span>系统设置，包括基本设置、数据库设置、网络转发配置、日志设置、颜色配置、短信告警设置、邮件转发设置等。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigtype</span></td><td style='text-align:left;' ><span>类型设置，为了增强灵活性拓展性，系统中的控制器类型、探测器类型、气体种类、气体符号等信息都可以在这里自定义。</span></td></tr></tbody></table></figure><h5 id='8342-模块-frmconfig2'><span>8.3.4.2 模块-frmconfig2</span></h5><p><span> </span><img src="snap/8-3-4-2.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmconfig2</span></td><td style='text-align:left;' ><span>其他设置模块主界面，采用堆栈窗体形式，加载多个子界面比如用户管理、位置调整等。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigdebug</span></td><td style='text-align:left;' ><span>数据打印调试，所有的设备数据通信都可以在这里看到，可以选择针对某个控制器和探测器，也可以选择只看发送还是接收的数据，所有的数据都有对应的解析文字，方便理解。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigmap</span></td><td style='text-align:left;' ><span>地图管理，可以添加删除地图图片文件。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigposition</span></td><td style='text-align:left;' ><span>位置调整，可以对地图上的设备拖动调整到合适的位置。</span></td></tr><tr><td style='text-align:left;' ><span>frmconfigscada</span></td><td style='text-align:left;' ><span>自定义控件属性设计器，演示如何加载自定义控件然后拖曳，导入导出xml文件，自定义用户数据，组态的雏形，目前功能单一。</span></td></tr></tbody></table></figure><h5 id='8343-模块-frmdata'><span>8.3.4.3 模块-frmdata</span></h5><p><span> </span><img src="snap/8-3-4-3.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmdata</span></td><td style='text-align:left;' ><span>日志查询模块主界面，采用堆栈窗体形式，加载多个子界面包括用户日志、运行日志、报警日志等。</span></td></tr><tr><td style='text-align:left;' ><span>frmdataalarm</span></td><td style='text-align:left;' ><span>报警日志，可以按照日期范围、报警类型等查询日志，查询后的日志可打印和导出，还可以删除指定日期范围的日志以及清空所有日志。</span></td></tr><tr><td style='text-align:left;' ><span>frmdatanode</span></td><td style='text-align:left;' ><span>运行日志，可以按照日期范围、控制器等查询日志，查询后的日志可打印和导出，还可以删除指定日期范围的日志以及清空所有日志。</span></td></tr><tr><td style='text-align:left;' ><span>frmdatauser</span></td><td style='text-align:left;' ><span>用户日志，可以按照日期范围、操作类型等查询日志，查询后的日志可打印和导出，还可以删除指定日期范围的日志以及清空所有日志。</span></td></tr></tbody></table></figure><h5 id='8344-模块-frmmain'><span>8.3.4.4 模块-frmmain</span></h5><p><span> </span><img src="snap/8-3-4-4.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmmain</span></td><td style='text-align:left;' ><span>系统主界面，采用堆栈窗体，加载各个子模块。</span></td></tr><tr><td style='text-align:left;' ><span>frmtool</span></td><td style='text-align:left;' ><span>模拟调试工具，可选择设备采集模拟或者数据库模拟。</span></td></tr><tr><td style='text-align:left;' ><span>frmtimecpu</span></td><td style='text-align:left;' ><span>时间和CPU内存模块，一般放在系统的右上角。</span></td></tr></tbody></table></figure><h5 id='8345-模块-frmother'><span>8.3.4.5 模块-frmother</span></h5><p><span> </span><img src="snap/8-3-4-5.jpg" referrerpolicy="no-referrer"><span>	</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmdevicecontrol</span></td><td style='text-align:left;' ><span>设备回控模块，目前就显示具体的探测器信息，后期按照用户需求定制。</span></td></tr><tr><td style='text-align:left;' ><span>frmdevicenode</span></td><td style='text-align:left;' ><span>设备面板模块，同时包含了多种面板样式比如普通样式、仪表样式，可以在系统设置中动态切换并立即应用，每个探测器在设备监控界面中都占用这样一个面板，显示具体的信息，包括实时更新值。</span></td></tr></tbody></table></figure><h5 id='8346-模块-frmview'><span>8.3.4.6 模块-frmview</span></h5><p><span> </span><img src="snap/8-3-4-6.jpg" referrerpolicy="no-referrer"></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>frmview</span></td><td style='text-align:left;' ><span>系统视图主界面，采用堆栈窗体，加载各个子模块。</span></td></tr><tr><td style='text-align:left;' ><span>frmviewdata</span></td><td style='text-align:left;' ><span>数据监控，表格形式展示每个设备的各项数据和单位，报警不同颜色显示，具体颜色可以在系统设置中设置。</span></td></tr><tr><td style='text-align:left;' ><span>frmviewdevice</span></td><td style='text-align:left;' ><span>设备监控，每个探测器都对应一个设备面板，超出则滚动条显示。</span></td></tr><tr><td style='text-align:left;' ><span>frmviewmap</span></td><td style='text-align:left;' ><span>地图监控，设备在图片地图上，报警后红色闪烁，可以双击弹出探测器的详细信息，同时在设备按钮上显示对应的采集到的值。</span></td></tr><tr><td style='text-align:left;' ><span>frmviewplot</span></td><td style='text-align:left;' ><span>曲线监控，可以指定某个探测器设备查看实时曲线，还可以看该设备的历史记录曲线。</span></td></tr></tbody></table></figure><h2 id='9-数据库设计'><span>9 数据库设计</span></h2><h3 id='91-端口信息-portinfo'><span>9.1 端口信息-PortInfo</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>PortID</span></td><td style='text-align:left;' ><span>编号</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' >&nbsp;</td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>PortName</span></td><td style='text-align:left;' ><span>端口名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>PortType</span></td><td style='text-align:left;' ><span>协议类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>15</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>ComName</span></td><td style='text-align:left;' ><span>串口号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>BaudRate</span></td><td style='text-align:left;' ><span>波特率</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>6</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>TcpIP</span></td><td style='text-align:left;' ><span>网络地址</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>16</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>TcpPort</span></td><td style='text-align:left;' ><span>网络端口</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>6</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>ReadInterval</span></td><td style='text-align:left;' ><span>采集周期</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>4</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>ReadTimeout</span></td><td style='text-align:left;' ><span>通讯超时次数</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>4</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>ReadMaxtime</span></td><td style='text-align:left;' ><span>超时重连时间</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>4</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>PortMark</span></td><td style='text-align:left;' ><span>备注</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>255</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='92-控制器信息-deviceinfo'><span>9.2 控制器信息-DeviceInfo</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>DeviceID</span></td><td style='text-align:left;' ><span>编号</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' >&nbsp;</td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>PortName</span></td><td style='text-align:left;' ><span>端口名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>DeviceName</span></td><td style='text-align:left;' ><span>控制器名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>DeviceAddr</span></td><td style='text-align:left;' ><span>控制器地址</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>3</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>DeviceType</span></td><td style='text-align:left;' ><span>控制器类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeNumber</span></td><td style='text-align:left;' ><span>探测器数量</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>3</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>DeviceMark</span></td><td style='text-align:left;' ><span>备注</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>255</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='93-探测器信息-nodeinfo'><span>9.3 探测器信息-NodeInfo</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>NodeID</span></td><td style='text-align:left;' ><span>编号</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' >&nbsp;</td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>positionID</span></td><td style='text-align:left;' ><span>位置编号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>DeviceName</span></td><td style='text-align:left;' ><span>控制器名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeName</span></td><td style='text-align:left;' ><span>探测器名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeAddr</span></td><td style='text-align:left;' ><span>探测器地址</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>3</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeType</span></td><td style='text-align:left;' ><span>探测器类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeClass</span></td><td style='text-align:left;' ><span>气体种类</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeSign</span></td><td style='text-align:left;' ><span>单位符号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeUpper</span></td><td style='text-align:left;' ><span>上限值</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeLimit</span></td><td style='text-align:left;' ><span>下限值</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeMax</span></td><td style='text-align:left;' ><span>最大值</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeMin</span></td><td style='text-align:left;' ><span>清零值</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeRange</span></td><td style='text-align:left;' ><span>缓冲值</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeEnable</span></td><td style='text-align:left;' ><span>启用禁用</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>2</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeSound</span></td><td style='text-align:left;' ><span>报警声音</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeImage</span></td><td style='text-align:left;' ><span>背景图片</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>SaveInterval</span></td><td style='text-align:left;' ><span>存储周期</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>3</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>DotCount</span></td><td style='text-align:left;' ><span>小数点位数</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>1</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>AlarmDelay</span></td><td style='text-align:left;' ><span>报警延时</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>3</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>AlarmType</span></td><td style='text-align:left;' ><span>报警类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>2</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeX</span></td><td style='text-align:left;' ><span>X坐标</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>4</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeY</span></td><td style='text-align:left;' ><span>Y坐标</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>4</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeMark</span></td><td style='text-align:left;' ><span>备注</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>255</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='94-报警联动-alarmlink'><span>9.4 报警联动-AlarmLink</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>PositionID</span></td><td style='text-align:left;' ><span>位置编号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>ComName</span></td><td style='text-align:left;' ><span>串口名</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>BaudRate</span></td><td style='text-align:left;' ><span>波特率</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>5</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>ModelAddr</span></td><td style='text-align:left;' ><span>模块地址</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>3</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>LinkAddr</span></td><td style='text-align:left;' ><span>联动地址集合</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>LinkEnable</span></td><td style='text-align:left;' ><span>启用禁用</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>2</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>LinkMark</span></td><td style='text-align:left;' ><span>备注</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>255</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='95-类型信息-typeinfo'><span>9.5 类型信息-TypeInfo</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>TypeID</span></td><td style='text-align:left;' ><span>编号</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' >&nbsp;</td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>DeviceType</span></td><td style='text-align:left;' ><span>控制器类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeNumber</span></td><td style='text-align:left;' ><span>探测器数量</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>5</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeType</span></td><td style='text-align:left;' ><span>探测器类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeClass</span></td><td style='text-align:left;' ><span>气体种类</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeSign</span></td><td style='text-align:left;' ><span>气体符号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='96-节点数据-nodedata'><span>9.6 节点数据-NodeData</span></h3><ol start='' ><li><span>此表对应数据库采集模式和数据库读取模式。</span></li><li><span>节点状态含义：0-离线、1-在线、2-低报、3-高报、4-失效。</span></li><li><span>本表用于给其他程序存入采集到的数据，本程序通过读取数据库采集数据。</span></li></ol><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>PositionID</span></td><td style='text-align:left;' ><span>位置编号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeValue</span></td><td style='text-align:left;' ><span>节点数据</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>NodeStatus</span></td><td style='text-align:left;' ><span>节点状态</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' ><span>2</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>SaveTime</span></td><td style='text-align:left;' ><span>记录时间</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>19</span></td><td style='text-align:left;' ><span>不为空</span></td></tr></tbody></table></figure><h3 id='97-用户信息-userinfo'><span>9.7 用户信息-UserInfo</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>UserName</span></td><td style='text-align:left;' ><span>用户名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>UserPwd</span></td><td style='text-align:left;' ><span>用户密码</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>UserType</span></td><td style='text-align:left;' ><span>用户类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' ><span>不为空</span></td></tr><tr><td style='text-align:left;' ><span>Permission1</span></td><td style='text-align:left;' ><span>用户权限1</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>Permission2</span></td><td style='text-align:left;' ><span>用户权限2</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>Permission3</span></td><td style='text-align:left;' ><span>用户权限3</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>Permission4</span></td><td style='text-align:left;' ><span>用户权限4</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>Permission5</span></td><td style='text-align:left;' ><span>用户权限5</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>Permission6</span></td><td style='text-align:left;' ><span>用户权限6</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>Permission7</span></td><td style='text-align:left;' ><span>用户权限7</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>UserMark</span></td><td style='text-align:left;' ><span>备注</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>50</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='98-操作记录-userlog'><span>9.8 操作记录-UserLog</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>LogID</span></td><td style='text-align:left;' ><span>编号</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' >&nbsp;</td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>TriggerTime</span></td><td style='text-align:left;' ><span>触发时间</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>19</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>UserName</span></td><td style='text-align:left;' ><span>用户名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>UserType</span></td><td style='text-align:left;' ><span>用户类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>LogType</span></td><td style='text-align:left;' ><span>事件类型</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>LogContent</span></td><td style='text-align:left;' ><span>事件内容</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>255</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='99-运行记录-nodelog'><span>9.9 运行记录-NodeLog</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>LogID</span></td><td style='text-align:left;' ><span>编号</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' >&nbsp;</td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>PositionID</span></td><td style='text-align:left;' ><span>位置编号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>DeviceName</span></td><td style='text-align:left;' ><span>控制器名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeName</span></td><td style='text-align:left;' ><span>探测器名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeValue</span></td><td style='text-align:left;' ><span>当前值</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeSign</span></td><td style='text-align:left;' ><span>单位符号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>SaveTime</span></td><td style='text-align:left;' ><span>保存时间</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>19</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>LogMark</span></td><td style='text-align:left;' ><span>备注</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>255</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h3 id='910-报警记录-alarmlog'><span>9.10 报警记录-AlarmLog</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>字段名</span></th><th style='text-align:left;' ><span>中文名</span></th><th style='text-align:left;' ><span>类型</span></th><th style='text-align:left;' ><span>长度</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>LogID</span></td><td style='text-align:left;' ><span>编号</span></td><td style='text-align:left;' ><span>INTEGER</span></td><td style='text-align:left;' >&nbsp;</td><td style='text-align:left;' ><span>主键自增</span></td></tr><tr><td style='text-align:left;' ><span>PositionID</span></td><td style='text-align:left;' ><span>位置编号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>DeviceName</span></td><td style='text-align:left;' ><span>控制器名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeName</span></td><td style='text-align:left;' ><span>探测器名称</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>30</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeValue</span></td><td style='text-align:left;' ><span>当前值</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>NodeSign</span></td><td style='text-align:left;' ><span>单位符号</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>10</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>Content</span></td><td style='text-align:left;' ><span>报警内容</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>StartTime</span></td><td style='text-align:left;' ><span>开始时间</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>19</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>EndTime</span></td><td style='text-align:left;' ><span>结束时间</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>19</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>ConfirmUser</span></td><td style='text-align:left;' ><span>确认用户</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>20</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>ConfirmTime</span></td><td style='text-align:left;' ><span>确认时间</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>19</span></td><td style='text-align:left;' >&nbsp;</td></tr><tr><td style='text-align:left;' ><span>ConfirmContent</span></td><td style='text-align:left;' ><span>确认意见</span></td><td style='text-align:left;' ><span>VARCHAR</span></td><td style='text-align:left;' ><span>255</span></td><td style='text-align:left;' >&nbsp;</td></tr></tbody></table></figure><h2 id='10-其他说明'><span>10 其他说明</span></h2><h3 id='101-设备模拟工具'><span>10.1 设备模拟工具</span></h3><p><span> </span><img src="snap/10-1-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-1-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-1-3.jpg" referrerpolicy="no-referrer"></p><p><span>本系统专门配备了设备模拟工具，用来在没有外接真实设备的时候，模拟modbus协议数据，支持多个设备，支持串口和网络方式，可切换正常数据和报警数据，反应到主程序上。对应主程序中两种端口，一种是串口端口（这个可以用虚拟串口工具 Virtual Serial Port 虚拟一对串口用于测试），一种是网络端口（注意选择的监听主机地址和端口）。数据库模拟对应程序中的数据库采集运行模式，可以勾选自动模拟复选框。随机生成状态字段数据。</span></p><h3 id='102-modbus仿真'><span>10.2 modbus仿真</span></h3><p><span> </span><img src="snap/10-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>作为国际知名的modbus模拟仿真工具Modbus Slave，本系统也提供了对应的数据配置文件iotsystem.mbs，在db目录下，对应添加FC-1003-8控制器。两边的通信方式必须一致，比如软件上设置的串口则两边都是串口。具体Modbus Slave工具详细使用可以自行搜索，比如这篇文章 </span><a href='https://blog.csdn.net/xuw_xy/article/details/81166305'><span>https://blog.csdn.net/xuw_xy/article/details/81166305</span></a><span> 。</span></p><h3 id='103-邮件转发设置'><span>10.3 邮件转发设置</span></h3><p><span> </span><img src="snap/10-3-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-3-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-3-3.jpg" referrerpolicy="no-referrer"></p><p><span>本系统支持邮件转发，前提是对应的邮箱账号需要开通 POP3/SMTP 等服务，按照图示开启即可，一般开启后会设置独立的管理密码，记得在系统设置那边的邮件转发，填写密码的时候要填的是独立管理密码，而不是邮箱号的密码，这个机制和任何第三方邮箱管理软件都一样。</span></p><h3 id='104-短信转发设置'><span>10.4 短信转发设置</span></h3><p><span> </span><img src="snap/10-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统支持串口短信发送，需要发短信的硬件支持（俗称DXM），采用通用的标准的AT指令短信发送协议，支持任意厂家的串口短信设备。当设备报警后会自动组建报警短信发送给设定的收件人。支持中文短信发送和长短信发送，可以自行网上GM对应的硬件。</span></p><h3 id='105-代码行数统计'><span>10.5 代码行数统计</span></h3><p><span> </span><img src="snap/10-5-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统除去第三方库（串口通信3rd_qextserialport、曲线图表3rd_qcustomplot、属性控件3rd_qtpropertybrowser、邮件发送3rd_smtpclient）的代码，总代码行数约4W行，纯代码行数约3W行。</span></p><h3 id='106-多种数据库支持'><span>10.6 多种数据库支持</span></h3><p><span>本系统支持多种数据库，包括sqlite、mysql、sqlserver、postgresql、oracle、kingbase等，直接在系统设置中的数据库配置中切换即可，切换完数据库以后记得初始化数据库，否则数据库不存在。</span></p><h4 id='1061-sqlite'><span>10.6.1 sqlite</span></h4><p><span> </span><img src="snap/10-6-1.jpg" referrerpolicy="no-referrer"></p><h4 id='1062-mysql'><span>10.6.2 mysql</span></h4><p><span> </span><img src="snap/10-6-2.jpg" referrerpolicy="no-referrer"></p><h4 id='1063-sqlserver'><span>10.6.3 sqlserver</span></h4><p><span> </span><img src="snap/10-6-3.jpg" referrerpolicy="no-referrer"></p><h4 id='1064-postgresql'><span>10.6.4 postgresql</span></h4><p><span> </span><img src="snap/10-6-4.jpg" referrerpolicy="no-referrer"></p><h4 id='1065-oracle'><span>10.6.5 oracle</span></h4><p><span> </span><img src="snap/10-6-5.jpg" referrerpolicy="no-referrer"></p><h4 id='1066-kingbase'><span>10.6.6 kingbase</span></h4><p><span> </span><img src="snap/10-6-6.jpg" referrerpolicy="no-referrer"></p><h3 id='107-采集数据转发'><span>10.7 采集数据转发</span></h3><p><span> </span><img src="snap/10-7-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-7-2.jpg" referrerpolicy="no-referrer"></p><p><span>在系统设置中设置好网络转发参数后，可以在接收的地方开启网络数据接收，这样只需要接收数据解析反应到界面就行，相当于数据源不是硬件设备而是网络转发过来的数据，不需要直接接硬件设备。</span></p><p><span>网络转发端，单击同步数据会把本地的端口信息、控制器信息、探测器信息发到远端。网络转发模块也可以作为无限级联使用，比如接收端还可以开启转发，继续转发给需要的地方，一个客户端上设置的转发也支持多个，用英文分号 ; 隔开，一对多关系，采用的无连接udp协议，几乎不占用系统资源。</span></p><h3 id='108-云端数据库同步'><span>10.8 云端数据库同步</span></h3><p><span> </span><img src="snap/10-8-1.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-8-2.jpg" referrerpolicy="no-referrer">
<span> </span><img src="snap/10-8-3.jpg" referrerpolicy="no-referrer"></p><p><span>云端数据库同步，相当于把本地采集到的数据实时存储到云端，至于这些记录到了云端后什么用途，一般会用来做web请求访问，或者app请求获取数据，具体应用看用户需求。</span></p><p><span>云端数据库也会存储到NodeData表中，意味着任意地方的客户端，都可以选择数据库采集模式，直接连接云端的数据库作为数据源。相当于可以无限级联。</span></p></div></div>

<script>(function(){var e=document.body.parentElement,t=[],n=null,i=document.body.classList.contains("typora-export-collapse-outline"),r=function(e,t,n){document.addEventListener(e,function(e){if(!e.defaultPrevented)for(var i=e.target;i&&i!=this;i=i.parentNode)if(i.matches(t)){!1===n.call(i,e)&&(e.preventDefault(),e.stopPropagation());break}},!1)};function o(){return e.scrollTop}r("click",".outline-expander",function(e){var t=this.closest(".outline-item-wrapper").classList;return t.contains("outline-item-open")?t.remove("outline-item-open"):t.add("outline-item-open"),d(),!1}),r("click",".outline-item",function(e){var t=this.querySelector(".outline-label");if(location.hash="#"+t.getAttribute("href"),i){var n=this.closest(".outline-item-wrapper").classList;n.contains("outline-item-open")||n.add("outline-item-open"),c(),n.add("outline-item-active")}});var a,s,l=function(){var e=o();n=null;for(var i=0;i<t.length&&t[i][1]-e<60;i++)n=t[i]},c=function(){document.querySelectorAll(".outline-item-active").forEach(e=>e.classList.remove("outline-item-active")),document.querySelectorAll(".outline-item-single.outline-item-open").forEach(e=>e.classList.remove("outline-item-open"))},d=function(){if(n){c();var e=document.querySelector('.outline-label[href="#'+(CSS.escape?CSS.escape(n[0]):n[0])+'"]');if(e)if(i){var t=e.closest(".outline-item-open>ul>.outline-item-wrapper");if(t)t.classList.add("outline-item-active");else{for(var r=(e=e.closest(".outline-item-wrapper")).parentElement.closest(".outline-item-wrapper");r;)r=(e=r).parentElement.closest(".outline-item-wrapper");e.classList.add("outline-item-active")}}else e.closest(".outline-item-wrapper").classList.add("outline-item-active")}};window.addEventListener("scroll",function(e){a&&clearTimeout(a),a=setTimeout(function(){l(),d()},300)});var u=function(){s=setTimeout(function(){!function(){t=[];var e=o();document.querySelector("#write").querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(n=>{var i=n.getAttribute("id");t.push([i,e+n.getBoundingClientRect().y])})}(),l(),d()},300)};window.addEventListener("resize",function(e){s&&clearTimeout(s),u()}),u()})();</script></body>
</html>